Mercurial > vim
comparison src/message.c @ 15470:55ccc2d353bd v8.1.0743
patch 8.1.0743: giving error messages is not flexible
commit https://github.com/vim/vim/commit/f9e3e09fdc93be9f0d47afbc6c7df1188c2a5a0d
Author: Bram Moolenaar <Bram@vim.org>
Date: Sun Jan 13 23:38:42 2019 +0100
patch 8.1.0743: giving error messages is not flexible
Problem: Giving error messages is not flexible.
Solution: Add semsg(). Change argument from "char_u *" to "char *", also
for msg() and get rid of most MSG macros. (Ozaki Kiichi, closes
#3302) Also make emsg() accept a "char *" argument. Get rid of
an enormous number of type casts.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sun, 13 Jan 2019 23:45:08 +0100 |
parents | dada0b389d4f |
children | bc17a9d37810 |
comparison
equal
deleted
inserted
replaced
15469:bc9b5261ed01 | 15470:55ccc2d353bd |
---|---|
356 } | 356 } |
357 } | 357 } |
358 | 358 |
359 /* | 359 /* |
360 * Automatic prototype generation does not understand this function. | 360 * Automatic prototype generation does not understand this function. |
361 * Note: Caller of smgs() and smsg_attr() must check the resulting string is | 361 * Note: Caller of smsg() and smsg_attr() must check the resulting string is |
362 * shorter than IOSIZE!!! | 362 * shorter than IOSIZE!!! |
363 */ | 363 */ |
364 #ifndef PROTO | 364 #ifndef PROTO |
365 | 365 |
366 int vim_snprintf(char *str, size_t str_m, char *fmt, ...); | 366 int vim_snprintf(char *str, size_t str_m, const char *fmt, ...); |
367 | 367 |
368 int | 368 int |
369 # ifdef __BORLANDC__ | 369 # ifdef __BORLANDC__ |
370 _RTLENTRYF | 370 _RTLENTRYF |
371 # endif | 371 # endif |
372 smsg(char_u *s, ...) | 372 smsg(const char *s, ...) |
373 { | 373 { |
374 va_list arglist; | 374 va_list arglist; |
375 | 375 |
376 va_start(arglist, s); | 376 va_start(arglist, s); |
377 vim_vsnprintf((char *)IObuff, IOSIZE, (char *)s, arglist); | 377 vim_vsnprintf((char *)IObuff, IOSIZE, s, arglist); |
378 va_end(arglist); | 378 va_end(arglist); |
379 return msg(IObuff); | 379 return msg(IObuff); |
380 } | 380 } |
381 | 381 |
382 int | 382 int |
383 # ifdef __BORLANDC__ | 383 # ifdef __BORLANDC__ |
384 _RTLENTRYF | 384 _RTLENTRYF |
385 # endif | 385 # endif |
386 smsg_attr(int attr, char_u *s, ...) | 386 smsg_attr(int attr, const char *s, ...) |
387 { | 387 { |
388 va_list arglist; | 388 va_list arglist; |
389 | 389 |
390 va_start(arglist, s); | 390 va_start(arglist, s); |
391 vim_vsnprintf((char *)IObuff, IOSIZE, (char *)s, arglist); | 391 vim_vsnprintf((char *)IObuff, IOSIZE, s, arglist); |
392 va_end(arglist); | 392 va_end(arglist); |
393 return msg_attr(IObuff, attr); | 393 return msg_attr(IObuff, attr); |
394 } | 394 } |
395 | 395 |
396 int | 396 int |
397 # ifdef __BORLANDC__ | 397 # ifdef __BORLANDC__ |
398 _RTLENTRYF | 398 _RTLENTRYF |
399 # endif | 399 # endif |
400 smsg_attr_keep(int attr, char_u *s, ...) | 400 smsg_attr_keep(int attr, const char *s, ...) |
401 { | 401 { |
402 va_list arglist; | 402 va_list arglist; |
403 | 403 |
404 va_start(arglist, s); | 404 va_start(arglist, s); |
405 vim_vsnprintf((char *)IObuff, IOSIZE, (char *)s, arglist); | 405 vim_vsnprintf((char *)IObuff, IOSIZE, s, arglist); |
406 va_end(arglist); | 406 va_end(arglist); |
407 return msg_attr_keep(IObuff, attr, TRUE); | 407 return msg_attr_keep(IObuff, attr, TRUE); |
408 } | 408 } |
409 | 409 |
410 #endif | 410 #endif |
580 void | 580 void |
581 do_perror(char *msg) | 581 do_perror(char *msg) |
582 { | 582 { |
583 perror(msg); | 583 perror(msg); |
584 ++emsg_silent; | 584 ++emsg_silent; |
585 emsg((char_u *)msg); | 585 emsg(msg); |
586 --emsg_silent; | 586 --emsg_silent; |
587 } | 587 } |
588 #endif | 588 #endif |
589 | 589 |
590 /* | 590 /* |
591 * emsg() - display an error message | 591 * emsg_core() - display an error message |
592 * | 592 * |
593 * Rings the bell, if appropriate, and calls message() to do the real work | 593 * Rings the bell, if appropriate, and calls message() to do the real work |
594 * When terminal not initialized (yet) mch_errmsg(..) is used. | 594 * When terminal not initialized (yet) mch_errmsg(..) is used. |
595 * | 595 * |
596 * return TRUE if wait_return not called | 596 * Return TRUE if wait_return not called. |
597 */ | 597 * Note: caller must check 'emsg_not_now()' before calling this. |
598 int | 598 */ |
599 emsg(char_u *s) | 599 static int |
600 emsg_core(char_u *s) | |
600 { | 601 { |
601 int attr; | 602 int attr; |
602 char_u *p; | 603 char_u *p; |
603 int r; | 604 int r; |
604 #ifdef FEAT_EVAL | 605 #ifdef FEAT_EVAL |
605 int ignore = FALSE; | 606 int ignore = FALSE; |
606 int severe; | 607 int severe; |
607 #endif | 608 #endif |
608 | |
609 /* Skip this if not giving error messages at the moment. */ | |
610 if (emsg_not_now()) | |
611 return TRUE; | |
612 | 609 |
613 #ifdef FEAT_EVAL | 610 #ifdef FEAT_EVAL |
614 /* When testing some errors are turned into a normal message. */ | 611 /* When testing some errors are turned into a normal message. */ |
615 if (ignore_error(s)) | 612 if (ignore_error(s)) |
616 /* don't call msg() if it results in a dialog */ | 613 /* don't call msg() if it results in a dialog */ |
725 emsg_to_channel_log = FALSE; | 722 emsg_to_channel_log = FALSE; |
726 #endif | 723 #endif |
727 return r; | 724 return r; |
728 } | 725 } |
729 | 726 |
730 | 727 /* |
731 /* | 728 * Print an error message. |
732 * Print an error message with one "%s" and one string argument. | |
733 */ | 729 */ |
734 int | 730 int |
735 emsg2(char_u *s, char_u *a1) | 731 emsg(char *s) |
736 { | 732 { |
737 return emsg3(s, a1, NULL); | 733 /* Skip this if not giving error messages at the moment. */ |
738 } | 734 if (!emsg_not_now()) |
739 | 735 return emsg_core((char_u *)s); |
740 /* | 736 return TRUE; /* no error messages at the moment */ |
741 * Print an error message with one or two "%s" and one or two string arguments. | 737 } |
742 * This is not in message.c to avoid a warning for prototypes. | 738 |
739 /* | |
740 * Print an error message with format string and variable arguments. | |
741 * Note: caller must not pass 'IObuff' as 1st argument. | |
743 */ | 742 */ |
744 int | 743 int |
745 emsg3(char_u *s, char_u *a1, char_u *a2) | 744 semsg(const char *s, ...) |
746 { | 745 { |
747 if (emsg_not_now()) | 746 /* Skip this if not giving error messages at the moment. */ |
748 return TRUE; /* no error messages at the moment */ | 747 if (!emsg_not_now()) |
749 vim_snprintf((char *)IObuff, IOSIZE, (char *)s, a1, a2); | 748 { |
750 return emsg(IObuff); | 749 va_list ap; |
751 } | 750 |
752 | 751 va_start(ap, s); |
753 /* | 752 vim_vsnprintf((char *)IObuff, IOSIZE, s, ap); |
754 * Print an error message with one "%ld" and one long int argument. | 753 va_end(ap); |
755 * This is not in message.c to avoid a warning for prototypes. | 754 return emsg_core(IObuff); |
756 */ | 755 } |
757 int | 756 return TRUE; /* no error messages at the moment */ |
758 emsgn(char_u *s, long n) | |
759 { | |
760 if (emsg_not_now()) | |
761 return TRUE; /* no error messages at the moment */ | |
762 vim_snprintf((char *)IObuff, IOSIZE, (char *)s, n); | |
763 return emsg(IObuff); | |
764 } | 757 } |
765 | 758 |
766 /* | 759 /* |
767 * Same as emsg(...), but abort on error when ABORT_ON_INTERNAL_ERROR is | 760 * Same as emsg(...), but abort on error when ABORT_ON_INTERNAL_ERROR is |
768 * defined. It is used for internal errors only, so that they can be | 761 * defined. It is used for internal errors only, so that they can be |
769 * detected when fuzzing vim. | 762 * detected when fuzzing vim. |
770 */ | 763 */ |
771 void | 764 void |
772 iemsg(char_u *s) | 765 iemsg(char *s) |
773 { | 766 { |
774 emsg(s); | 767 if (!emsg_not_now()) |
768 emsg_core((char_u *)s); | |
775 #ifdef ABORT_ON_INTERNAL_ERROR | 769 #ifdef ABORT_ON_INTERNAL_ERROR |
776 abort(); | 770 abort(); |
777 #endif | 771 #endif |
778 } | 772 } |
779 | 773 |
780 | 774 /* |
781 /* | 775 * Same as semsg(...) but abort on error when ABORT_ON_INTERNAL_ERROR is |
782 * Same as emsg2(...) but abort on error when ABORT_ON_INTERNAL_ERROR is | |
783 * defined. It is used for internal errors only, so that they can be | 776 * defined. It is used for internal errors only, so that they can be |
784 * detected when fuzzing vim. | 777 * detected when fuzzing vim. |
778 * Note: caller must not pass 'IObuff' as 1st argument. | |
785 */ | 779 */ |
786 void | 780 void |
787 iemsg2(char_u *s, char_u *a1) | 781 siemsg(const char *s, ...) |
788 { | 782 { |
789 emsg2(s, a1); | 783 if (!emsg_not_now()) |
784 { | |
785 va_list ap; | |
786 | |
787 va_start(ap, s); | |
788 vim_vsnprintf((char *)IObuff, IOSIZE, s, ap); | |
789 va_end(ap); | |
790 emsg_core(IObuff); | |
791 } | |
790 #ifdef ABORT_ON_INTERNAL_ERROR | 792 #ifdef ABORT_ON_INTERNAL_ERROR |
791 abort(); | 793 abort(); |
792 #endif | 794 #endif |
793 } | 795 } |
794 | 796 |
795 /* | 797 /* |
796 * Same as emsgn(...) but abort on error when ABORT_ON_INTERNAL_ERROR is | |
797 * defined. It is used for internal errors only, so that they can be | |
798 * detected when fuzzing vim. | |
799 */ | |
800 void | |
801 iemsgn(char_u *s, long n) | |
802 { | |
803 emsgn(s, n); | |
804 #ifdef ABORT_ON_INTERNAL_ERROR | |
805 abort(); | |
806 #endif | |
807 } | |
808 | |
809 /* | |
810 * Give an "Internal error" message. | 798 * Give an "Internal error" message. |
811 */ | 799 */ |
812 void | 800 void |
813 internal_error(char *where) | 801 internal_error(char *where) |
814 { | 802 { |
815 IEMSG2(_(e_intern2), where); | 803 siemsg(_(e_intern2), where); |
816 } | 804 } |
817 | 805 |
818 /* emsg3() and emsgn() are in misc2.c to avoid warnings for the prototypes. */ | 806 /* emsg3() and emsgn() are in misc2.c to avoid warnings for the prototypes. */ |
819 | 807 |
820 void | 808 void |
821 emsg_invreg(int name) | 809 emsg_invreg(int name) |
822 { | 810 { |
823 EMSG2(_("E354: Invalid register name: '%s'"), transchar(name)); | 811 semsg(_("E354: Invalid register name: '%s'"), transchar(name)); |
824 } | 812 } |
825 | 813 |
826 /* | 814 /* |
827 * Like msg(), but truncate to a single line if p_shm contains 't', or when | 815 * Like msg(), but truncate to a single line if p_shm contains 't', or when |
828 * "force" is TRUE. This truncates in another way as for normal messages. | 816 * "force" is TRUE. This truncates in another way as for normal messages. |
967 return; | 955 return; |
968 } | 956 } |
969 | 957 |
970 if (*eap->arg != NUL) | 958 if (*eap->arg != NUL) |
971 { | 959 { |
972 EMSG(_(e_invarg)); | 960 emsg(_(e_invarg)); |
973 return; | 961 return; |
974 } | 962 } |
975 | 963 |
976 msg_hist_off = TRUE; | 964 msg_hist_off = TRUE; |
977 | 965 |
3471 verbose_did_open = TRUE; | 3459 verbose_did_open = TRUE; |
3472 | 3460 |
3473 verbose_fd = mch_fopen((char *)p_vfile, "a"); | 3461 verbose_fd = mch_fopen((char *)p_vfile, "a"); |
3474 if (verbose_fd == NULL) | 3462 if (verbose_fd == NULL) |
3475 { | 3463 { |
3476 EMSG2(_(e_notopen), p_vfile); | 3464 semsg(_(e_notopen), p_vfile); |
3477 return FAIL; | 3465 return FAIL; |
3478 } | 3466 } |
3479 } | 3467 } |
3480 return OK; | 3468 return OK; |
3481 } | 3469 } |
4090 } | 4078 } |
4091 else | 4079 else |
4092 # endif | 4080 # endif |
4093 { | 4081 { |
4094 /* TODO: non-GUI file selector here */ | 4082 /* TODO: non-GUI file selector here */ |
4095 EMSG(_("E338: Sorry, no file browser in console mode")); | 4083 emsg(_("E338: Sorry, no file browser in console mode")); |
4096 fname = NULL; | 4084 fname = NULL; |
4097 } | 4085 } |
4098 | 4086 |
4099 /* keep the directory for next time */ | 4087 /* keep the directory for next time */ |
4100 if (fname != NULL) | 4088 if (fname != NULL) |
4134 int idx = *idxp - 1; | 4122 int idx = *idxp - 1; |
4135 varnumber_T n = 0; | 4123 varnumber_T n = 0; |
4136 int err = FALSE; | 4124 int err = FALSE; |
4137 | 4125 |
4138 if (tvs[idx].v_type == VAR_UNKNOWN) | 4126 if (tvs[idx].v_type == VAR_UNKNOWN) |
4139 EMSG(_(e_printf)); | 4127 emsg(_(e_printf)); |
4140 else | 4128 else |
4141 { | 4129 { |
4142 ++*idxp; | 4130 ++*idxp; |
4143 n = tv_get_number_chk(&tvs[idx], &err); | 4131 n = tv_get_number_chk(&tvs[idx], &err); |
4144 if (err) | 4132 if (err) |
4161 int idx = *idxp - 1; | 4149 int idx = *idxp - 1; |
4162 char *s = NULL; | 4150 char *s = NULL; |
4163 static char_u numbuf[NUMBUFLEN]; | 4151 static char_u numbuf[NUMBUFLEN]; |
4164 | 4152 |
4165 if (tvs[idx].v_type == VAR_UNKNOWN) | 4153 if (tvs[idx].v_type == VAR_UNKNOWN) |
4166 EMSG(_(e_printf)); | 4154 emsg(_(e_printf)); |
4167 else | 4155 else |
4168 { | 4156 { |
4169 ++*idxp; | 4157 ++*idxp; |
4170 if (tofree != NULL) | 4158 if (tofree != NULL) |
4171 s = (char *)echo_string(&tvs[idx], tofree, numbuf, get_copyID()); | 4159 s = (char *)echo_string(&tvs[idx], tofree, numbuf, get_copyID()); |
4184 { | 4172 { |
4185 int idx = *idxp - 1; | 4173 int idx = *idxp - 1; |
4186 double f = 0; | 4174 double f = 0; |
4187 | 4175 |
4188 if (tvs[idx].v_type == VAR_UNKNOWN) | 4176 if (tvs[idx].v_type == VAR_UNKNOWN) |
4189 EMSG(_(e_printf)); | 4177 emsg(_(e_printf)); |
4190 else | 4178 else |
4191 { | 4179 { |
4192 ++*idxp; | 4180 ++*idxp; |
4193 if (tvs[idx].v_type == VAR_FLOAT) | 4181 if (tvs[idx].v_type == VAR_FLOAT) |
4194 f = tvs[idx].vval.v_float; | 4182 f = tvs[idx].vval.v_float; |
4195 else if (tvs[idx].v_type == VAR_NUMBER) | 4183 else if (tvs[idx].v_type == VAR_NUMBER) |
4196 f = (double)tvs[idx].vval.v_number; | 4184 f = (double)tvs[idx].vval.v_number; |
4197 else | 4185 else |
4198 EMSG(_("E807: Expected Float argument for printf()")); | 4186 emsg(_("E807: Expected Float argument for printf()")); |
4199 } | 4187 } |
4200 return f; | 4188 return f; |
4201 } | 4189 } |
4202 # endif | 4190 # endif |
4203 #endif | 4191 #endif |
4272 * understand this. */ | 4260 * understand this. */ |
4273 #ifndef PROTO | 4261 #ifndef PROTO |
4274 | 4262 |
4275 /* Like vim_vsnprintf() but append to the string. */ | 4263 /* Like vim_vsnprintf() but append to the string. */ |
4276 int | 4264 int |
4277 vim_snprintf_add(char *str, size_t str_m, char *fmt, ...) | 4265 vim_snprintf_add(char *str, size_t str_m, const char *fmt, ...) |
4278 { | 4266 { |
4279 va_list ap; | 4267 va_list ap; |
4280 int str_l; | 4268 int str_l; |
4281 size_t len = STRLEN(str); | 4269 size_t len = STRLEN(str); |
4282 size_t space; | 4270 size_t space; |
4290 va_end(ap); | 4278 va_end(ap); |
4291 return str_l; | 4279 return str_l; |
4292 } | 4280 } |
4293 | 4281 |
4294 int | 4282 int |
4295 vim_snprintf(char *str, size_t str_m, char *fmt, ...) | 4283 vim_snprintf(char *str, size_t str_m, const char *fmt, ...) |
4296 { | 4284 { |
4297 va_list ap; | 4285 va_list ap; |
4298 int str_l; | 4286 int str_l; |
4299 | 4287 |
4300 va_start(ap, fmt); | 4288 va_start(ap, fmt); |
4305 | 4293 |
4306 int | 4294 int |
4307 vim_vsnprintf( | 4295 vim_vsnprintf( |
4308 char *str, | 4296 char *str, |
4309 size_t str_m, | 4297 size_t str_m, |
4310 char *fmt, | 4298 const char *fmt, |
4311 va_list ap) | 4299 va_list ap) |
4312 { | 4300 { |
4313 return vim_vsnprintf_typval(str, str_m, fmt, ap, NULL); | 4301 return vim_vsnprintf_typval(str, str_m, fmt, ap, NULL); |
4314 } | 4302 } |
4315 | 4303 |
4316 int | 4304 int |
4317 vim_vsnprintf_typval( | 4305 vim_vsnprintf_typval( |
4318 char *str, | 4306 char *str, |
4319 size_t str_m, | 4307 size_t str_m, |
4320 char *fmt, | 4308 const char *fmt, |
4321 va_list ap, | 4309 va_list ap, |
4322 typval_T *tvs) | 4310 typval_T *tvs) |
4323 { | 4311 { |
4324 size_t str_l = 0; | 4312 size_t str_l = 0; |
4325 char *p = fmt; | 4313 const char *p = fmt; |
4326 int arg_idx = 1; | 4314 int arg_idx = 1; |
4327 | 4315 |
4328 if (p == NULL) | 4316 if (p == NULL) |
4329 p = ""; | 4317 p = ""; |
4330 while (*p != NUL) | 4318 while (*p != NUL) |
4368 # define TMP_LEN 34 | 4356 # define TMP_LEN 34 |
4369 # endif | 4357 # endif |
4370 char tmp[TMP_LEN]; | 4358 char tmp[TMP_LEN]; |
4371 | 4359 |
4372 /* string address in case of string argument */ | 4360 /* string address in case of string argument */ |
4373 char *str_arg; | 4361 const char *str_arg = NULL; |
4374 | 4362 |
4375 /* natural field width of arg without padding and sign */ | 4363 /* natural field width of arg without padding and sign */ |
4376 size_t str_arg_l; | 4364 size_t str_arg_l; |
4377 | 4365 |
4378 /* unsigned char argument value - only defined for c conversion. | 4366 /* unsigned char argument value - only defined for c conversion. |
4392 | 4380 |
4393 /* buffer for 's' and 'S' specs */ | 4381 /* buffer for 's' and 'S' specs */ |
4394 char_u *tofree = NULL; | 4382 char_u *tofree = NULL; |
4395 | 4383 |
4396 | 4384 |
4397 str_arg = NULL; | |
4398 p++; /* skip '%' */ | 4385 p++; /* skip '%' */ |
4399 | 4386 |
4400 /* parse flags */ | 4387 /* parse flags */ |
4401 while (*p == '0' || *p == '-' || *p == '+' || *p == ' ' | 4388 while (*p == '0' || *p == '-' || *p == '+' || *p == ' ' |
4402 || *p == '#' || *p == '\'') | 4389 || *p == '#' || *p == '\'') |
5237 * */ | 5224 * */ |
5238 str[str_l <= str_m - 1 ? str_l : str_m - 1] = '\0'; | 5225 str[str_l <= str_m - 1 ? str_l : str_m - 1] = '\0'; |
5239 } | 5226 } |
5240 | 5227 |
5241 if (tvs != NULL && tvs[arg_idx - 1].v_type != VAR_UNKNOWN) | 5228 if (tvs != NULL && tvs[arg_idx - 1].v_type != VAR_UNKNOWN) |
5242 EMSG(_("E767: Too many arguments to printf()")); | 5229 emsg(_("E767: Too many arguments to printf()")); |
5243 | 5230 |
5244 /* Return the number of characters formatted (excluding trailing nul | 5231 /* Return the number of characters formatted (excluding trailing nul |
5245 * character), that is, the number of characters that would have been | 5232 * character), that is, the number of characters that would have been |
5246 * written to the buffer if it were large enough. */ | 5233 * written to the buffer if it were large enough. */ |
5247 return (int)str_l; | 5234 return (int)str_l; |