@@ -320,6 +320,17 @@ free_msglist(l)
320320 }
321321}
322322
323+ /*
324+ * Free global "*msg_list" and the messages it contains, then set "*msg_list"
325+ * to NULL.
326+ */
327+ void
328+ free_global_msglist ()
329+ {
330+ free_msglist (* msg_list );
331+ * msg_list = NULL ;
332+ }
333+
323334/*
324335 * Throw the message specified in the call to cause_errthrow() above as an
325336 * error exception. If cstack is NULL, postpone the throw until do_cmdline()
@@ -410,66 +421,41 @@ do_intthrow(cstack)
410421 return TRUE;
411422}
412423
413-
414424/*
415- * Throw a new exception. Return FAIL when out of memory or it was tried to
416- * throw an illegal user exception. "value" is the exception string for a user
417- * or interrupt exception, or points to a message list in case of an error
418- * exception.
425+ * Get an exception message that is to be stored in current_exception->value.
419426 */
420- static int
421- throw_exception (value , type , cmdname )
427+ char_u *
428+ get_exception_string (value , type , cmdname , should_free )
422429 void * value ;
423430 int type ;
424431 char_u * cmdname ;
432+ int * should_free ;
425433{
426- except_T * excp ;
427- char_u * p , * mesg , * val ;
434+ char_u * ret , * mesg ;
428435 int cmdlen ;
429-
430- /*
431- * Disallow faking Interrupt or error exceptions as user exceptions. They
432- * would be treated differently from real interrupt or error exceptions when
433- * no active try block is found, see do_cmdline().
434- */
435- if (type == ET_USER )
436- {
437- if (STRNCMP ((char_u * )value , "Vim" , 3 ) == 0 &&
438- (((char_u * )value )[3 ] == NUL || ((char_u * )value )[3 ] == ':' ||
439- ((char_u * )value )[3 ] == '(' ))
440- {
441- EMSG (_ ("E608: Cannot :throw exceptions with 'Vim' prefix" ));
442- goto fail ;
443- }
444- }
445-
446- excp = (except_T * )alloc ((unsigned )sizeof (except_T ));
447- if (excp == NULL )
448- goto nomem ;
436+ char_u * p , * val ;
449437
450438 if (type == ET_ERROR )
451439 {
452- /* Store the original message and prefix the exception value with
453- * "Vim:" or, if a command name is given, "Vim(cmdname):". */
454- excp -> messages = (struct msglist * )value ;
455- mesg = excp -> messages -> throw_msg ;
440+ * should_free = FALSE;
441+ mesg = ((struct msglist * )value )-> throw_msg ;
456442 if (cmdname != NULL && * cmdname != NUL )
457443 {
458444 cmdlen = (int )STRLEN (cmdname );
459- excp -> value = vim_strnsave ((char_u * )"Vim(" ,
445+ ret = vim_strnsave ((char_u * )"Vim(" ,
460446 4 + cmdlen + 2 + (int )STRLEN (mesg ));
461- if (excp -> value == NULL )
462- goto nomem ;
463- STRCPY (& excp -> value [4 ], cmdname );
464- STRCPY (& excp -> value [4 + cmdlen ], "):" );
465- val = excp -> value + 4 + cmdlen + 2 ;
447+ if (ret == NULL )
448+ return ret ;
449+ STRCPY (& ret [4 ], cmdname );
450+ STRCPY (& ret [4 + cmdlen ], "):" );
451+ val = ret + 4 + cmdlen + 2 ;
466452 }
467453 else
468454 {
469- excp -> value = vim_strnsave ((char_u * )"Vim:" , 4 + (int )STRLEN (mesg ));
470- if (excp -> value == NULL )
471- goto nomem ;
472- val = excp -> value + 4 ;
455+ ret = vim_strnsave ((char_u * )"Vim:" , 4 + (int )STRLEN (mesg ));
456+ if (ret == NULL )
457+ return ret ;
458+ val = ret + 4 ;
473459 }
474460
475461 /* msg_add_fname may have been used to prefix the message with a file
@@ -506,14 +492,65 @@ throw_exception(value, type, cmdname)
506492 }
507493 }
508494 else
509- excp -> value = value ;
495+ {
496+ * should_free = FALSE;
497+ ret = (char_u * ) value ;
498+ }
499+
500+ return ret ;
501+ }
502+
503+
504+ /*
505+ * Throw a new exception. Return FAIL when out of memory or it was tried to
506+ * throw an illegal user exception. "value" is the exception string for a
507+ * user or interrupt exception, or points to a message list in case of an
508+ * error exception.
509+ */
510+ static int
511+ throw_exception (value , type , cmdname )
512+ void * value ;
513+ int type ;
514+ char_u * cmdname ;
515+ {
516+ except_T * excp ;
517+ int should_free ;
518+
519+ /*
520+ * Disallow faking Interrupt or error exceptions as user exceptions. They
521+ * would be treated differently from real interrupt or error exceptions
522+ * when no active try block is found, see do_cmdline().
523+ */
524+ if (type == ET_USER )
525+ {
526+ if (STRNCMP ((char_u * )value , "Vim" , 3 ) == 0
527+ && (((char_u * )value )[3 ] == NUL || ((char_u * )value )[3 ] == ':'
528+ || ((char_u * )value )[3 ] == '(' ))
529+ {
530+ EMSG (_ ("E608: Cannot :throw exceptions with 'Vim' prefix" ));
531+ goto fail ;
532+ }
533+ }
534+
535+ excp = (except_T * )alloc ((unsigned )sizeof (except_T ));
536+ if (excp == NULL )
537+ goto nomem ;
538+
539+ if (type == ET_ERROR )
540+ /* Store the original message and prefix the exception value with
541+ * "Vim:" or, if a command name is given, "Vim(cmdname):". */
542+ excp -> messages = (struct msglist * )value ;
543+
544+ excp -> value = get_exception_string (value , type , cmdname , & should_free );
545+ if (excp -> value == NULL && should_free )
546+ goto nomem ;
510547
511548 excp -> type = type ;
512549 excp -> throw_name = vim_strsave (sourcing_name == NULL
513550 ? (char_u * )"" : sourcing_name );
514551 if (excp -> throw_name == NULL )
515552 {
516- if (type == ET_ERROR )
553+ if (should_free )
517554 vim_free (excp -> value );
518555 goto nomem ;
519556 }
@@ -2033,10 +2070,7 @@ leave_cleanup(csp)
20332070 /* If an error was about to be converted to an exception when
20342071 * enter_cleanup() was called, free the message list. */
20352072 if (msg_list != NULL )
2036- {
2037- free_msglist (* msg_list );
2038- * msg_list = NULL ;
2039- }
2073+ free_global_msglist ();
20402074 }
20412075
20422076 /*
0 commit comments