Mercurial > vim
comparison src/channel.c @ 16872:a836d122231a v8.1.1437
patch 8.1.1437: code to handle callbacks is duplicated
commit https://github.com/vim/vim/commit/3a97bb3f0f8bd118ae23f1c97e55d84ff42eef20
Author: Bram Moolenaar <Bram@vim.org>
Date: Sat Jun 1 13:28:35 2019 +0200
patch 8.1.1437: code to handle callbacks is duplicated
Problem: Code to handle callbacks is duplicated.
Solution: Add callback_T and functions to deal with it.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sat, 01 Jun 2019 13:30:07 +0200 |
parents | ce04ebdf26b8 |
children | a5e3509b33ca |
comparison
equal
deleted
inserted
replaced
16871:e5dab34ded73 | 16872:a836d122231a |
---|---|
346 /* If the job was killed the channel is not expected to work anymore. */ | 346 /* If the job was killed the channel is not expected to work anymore. */ |
347 if (channel->ch_job_killed && channel->ch_job == NULL) | 347 if (channel->ch_job_killed && channel->ch_job == NULL) |
348 return FALSE; | 348 return FALSE; |
349 | 349 |
350 /* If there is a close callback it may still need to be invoked. */ | 350 /* If there is a close callback it may still need to be invoked. */ |
351 if (channel->ch_close_cb != NULL) | 351 if (channel->ch_close_cb.cb_name != NULL) |
352 return TRUE; | 352 return TRUE; |
353 | 353 |
354 /* If reading from or a buffer it's still useful. */ | 354 /* If reading from or a buffer it's still useful. */ |
355 if (channel->ch_part[PART_IN].ch_bufref.br_buf != NULL) | 355 if (channel->ch_part[PART_IN].ch_bufref.br_buf != NULL) |
356 return TRUE; | 356 return TRUE; |
364 || channel->ch_part[PART_OUT].ch_head.rq_next != NULL | 364 || channel->ch_part[PART_OUT].ch_head.rq_next != NULL |
365 || channel->ch_part[PART_OUT].ch_json_head.jq_next != NULL; | 365 || channel->ch_part[PART_OUT].ch_json_head.jq_next != NULL; |
366 has_err_msg = channel->ch_part[PART_ERR].ch_fd != INVALID_FD | 366 has_err_msg = channel->ch_part[PART_ERR].ch_fd != INVALID_FD |
367 || channel->ch_part[PART_ERR].ch_head.rq_next != NULL | 367 || channel->ch_part[PART_ERR].ch_head.rq_next != NULL |
368 || channel->ch_part[PART_ERR].ch_json_head.jq_next != NULL; | 368 || channel->ch_part[PART_ERR].ch_json_head.jq_next != NULL; |
369 return (channel->ch_callback != NULL && (has_sock_msg | 369 return (channel->ch_callback.cb_name != NULL && (has_sock_msg |
370 || has_out_msg || has_err_msg)) | 370 || has_out_msg || has_err_msg)) |
371 || ((channel->ch_part[PART_OUT].ch_callback != NULL | 371 || ((channel->ch_part[PART_OUT].ch_callback.cb_name != NULL |
372 || channel->ch_part[PART_OUT].ch_bufref.br_buf != NULL) | 372 || channel->ch_part[PART_OUT].ch_bufref.br_buf != NULL) |
373 && has_out_msg) | 373 && has_out_msg) |
374 || ((channel->ch_part[PART_ERR].ch_callback != NULL | 374 || ((channel->ch_part[PART_ERR].ch_callback.cb_name != NULL |
375 || channel->ch_part[PART_ERR].ch_bufref.br_buf != NULL) | 375 || channel->ch_part[PART_ERR].ch_bufref.br_buf != NULL) |
376 && has_err_msg); | 376 && has_err_msg); |
377 } | 377 } |
378 | 378 |
379 /* | 379 /* |
1176 } | 1176 } |
1177 | 1177 |
1178 return buf; | 1178 return buf; |
1179 } | 1179 } |
1180 | 1180 |
1181 /* | |
1182 * Copy callback from "src" to "dest", incrementing the refcounts. | |
1183 */ | |
1181 static void | 1184 static void |
1182 set_callback( | 1185 copy_callback(callback_T *dest, callback_T *src) |
1183 char_u **cbp, | 1186 { |
1184 partial_T **pp, | 1187 dest->cb_partial = src->cb_partial; |
1185 char_u *callback, | 1188 if (dest->cb_partial != NULL) |
1186 partial_T *partial) | 1189 { |
1187 { | 1190 dest->cb_name = src->cb_name; |
1188 free_callback(*cbp, *pp); | 1191 dest->cb_free_name = FALSE; |
1189 if (callback != NULL && *callback != NUL) | 1192 ++dest->cb_partial->pt_refcount; |
1190 { | |
1191 if (partial != NULL) | |
1192 *cbp = partial_name(partial); | |
1193 else | |
1194 { | |
1195 *cbp = vim_strsave(callback); | |
1196 func_ref(*cbp); | |
1197 } | |
1198 } | 1193 } |
1199 else | 1194 else |
1200 *cbp = NULL; | 1195 { |
1201 *pp = partial; | 1196 dest->cb_name = vim_strsave(src->cb_name); |
1202 if (partial != NULL) | 1197 dest->cb_free_name = TRUE; |
1203 ++partial->pt_refcount; | 1198 func_ref(src->cb_name); |
1199 } | |
1200 } | |
1201 | |
1202 static void | |
1203 free_set_callback(callback_T *cbp, callback_T *callback) | |
1204 { | |
1205 free_callback(cbp); | |
1206 | |
1207 if (callback->cb_name != NULL && *callback->cb_name != NUL) | |
1208 copy_callback(cbp, callback); | |
1209 else | |
1210 cbp->cb_name = NULL; | |
1204 } | 1211 } |
1205 | 1212 |
1206 /* | 1213 /* |
1207 * Set various properties from an "opt" argument. | 1214 * Set various properties from an "opt" argument. |
1208 */ | 1215 */ |
1231 channel->ch_part[PART_ERR].ch_timeout = opt->jo_err_timeout; | 1238 channel->ch_part[PART_ERR].ch_timeout = opt->jo_err_timeout; |
1232 if (opt->jo_set & JO_BLOCK_WRITE) | 1239 if (opt->jo_set & JO_BLOCK_WRITE) |
1233 channel->ch_part[PART_IN].ch_block_write = 1; | 1240 channel->ch_part[PART_IN].ch_block_write = 1; |
1234 | 1241 |
1235 if (opt->jo_set & JO_CALLBACK) | 1242 if (opt->jo_set & JO_CALLBACK) |
1236 set_callback(&channel->ch_callback, &channel->ch_partial, | 1243 free_set_callback(&channel->ch_callback, &opt->jo_callback); |
1237 opt->jo_callback, opt->jo_partial); | |
1238 if (opt->jo_set & JO_OUT_CALLBACK) | 1244 if (opt->jo_set & JO_OUT_CALLBACK) |
1239 set_callback(&channel->ch_part[PART_OUT].ch_callback, | 1245 free_set_callback(&channel->ch_part[PART_OUT].ch_callback, |
1240 &channel->ch_part[PART_OUT].ch_partial, | 1246 &opt->jo_out_cb); |
1241 opt->jo_out_cb, opt->jo_out_partial); | |
1242 if (opt->jo_set & JO_ERR_CALLBACK) | 1247 if (opt->jo_set & JO_ERR_CALLBACK) |
1243 set_callback(&channel->ch_part[PART_ERR].ch_callback, | 1248 free_set_callback(&channel->ch_part[PART_ERR].ch_callback, |
1244 &channel->ch_part[PART_ERR].ch_partial, | 1249 &opt->jo_err_cb); |
1245 opt->jo_err_cb, opt->jo_err_partial); | |
1246 if (opt->jo_set & JO_CLOSE_CALLBACK) | 1250 if (opt->jo_set & JO_CLOSE_CALLBACK) |
1247 set_callback(&channel->ch_close_cb, &channel->ch_close_partial, | 1251 free_set_callback(&channel->ch_close_cb, &opt->jo_close_cb); |
1248 opt->jo_close_cb, opt->jo_close_partial); | |
1249 channel->ch_drop_never = opt->jo_drop_never; | 1252 channel->ch_drop_never = opt->jo_drop_never; |
1250 | 1253 |
1251 if ((opt->jo_set & JO_OUT_IO) && opt->jo_io[PART_OUT] == JIO_BUFFER) | 1254 if ((opt->jo_set & JO_OUT_IO) && opt->jo_io[PART_OUT] == JIO_BUFFER) |
1252 { | 1255 { |
1253 buf_T *buf; | 1256 buf_T *buf; |
1347 */ | 1350 */ |
1348 void | 1351 void |
1349 channel_set_req_callback( | 1352 channel_set_req_callback( |
1350 channel_T *channel, | 1353 channel_T *channel, |
1351 ch_part_T part, | 1354 ch_part_T part, |
1352 char_u *callback, | 1355 callback_T *callback, |
1353 partial_T *partial, | |
1354 int id) | 1356 int id) |
1355 { | 1357 { |
1356 cbq_T *head = &channel->ch_part[part].ch_cb_head; | 1358 cbq_T *head = &channel->ch_part[part].ch_cb_head; |
1357 cbq_T *item = ALLOC_ONE(cbq_T); | 1359 cbq_T *item = ALLOC_ONE(cbq_T); |
1358 | 1360 |
1359 if (item != NULL) | 1361 if (item != NULL) |
1360 { | 1362 { |
1361 item->cq_partial = partial; | 1363 copy_callback(&item->cq_callback, callback); |
1362 if (partial != NULL) | |
1363 { | |
1364 ++partial->pt_refcount; | |
1365 item->cq_callback = callback; | |
1366 } | |
1367 else | |
1368 { | |
1369 item->cq_callback = vim_strsave(callback); | |
1370 func_ref(item->cq_callback); | |
1371 } | |
1372 item->cq_seq_nr = id; | 1364 item->cq_seq_nr = id; |
1373 item->cq_prev = head->cq_prev; | 1365 item->cq_prev = head->cq_prev; |
1374 head->cq_prev = item; | 1366 head->cq_prev = item; |
1375 item->cq_next = NULL; | 1367 item->cq_next = NULL; |
1376 if (item->cq_prev == NULL) | 1368 if (item->cq_prev == NULL) |
1636 /* | 1628 /* |
1637 * Invoke the "callback" on channel "channel". | 1629 * Invoke the "callback" on channel "channel". |
1638 * This does not redraw but sets channel_need_redraw; | 1630 * This does not redraw but sets channel_need_redraw; |
1639 */ | 1631 */ |
1640 static void | 1632 static void |
1641 invoke_callback(channel_T *channel, char_u *callback, partial_T *partial, | 1633 invoke_callback(channel_T *channel, callback_T *callback, typval_T *argv) |
1642 typval_T *argv) | |
1643 { | 1634 { |
1644 typval_T rettv; | 1635 typval_T rettv; |
1645 int dummy; | 1636 int dummy; |
1646 | 1637 |
1647 if (safe_to_invoke_callback == 0) | 1638 if (safe_to_invoke_callback == 0) |
1648 iemsg("INTERNAL: Invoking callback when it is not safe"); | 1639 iemsg("INTERNAL: Invoking callback when it is not safe"); |
1649 | 1640 |
1650 argv[0].v_type = VAR_CHANNEL; | 1641 argv[0].v_type = VAR_CHANNEL; |
1651 argv[0].vval.v_channel = channel; | 1642 argv[0].vval.v_channel = channel; |
1652 | 1643 |
1653 call_func(callback, -1, &rettv, 2, argv, NULL, | 1644 call_callback(callback, -1, &rettv, 2, argv, NULL, |
1654 0L, 0L, &dummy, TRUE, partial, NULL); | 1645 0L, 0L, &dummy, TRUE, NULL); |
1655 clear_tv(&rettv); | 1646 clear_tv(&rettv); |
1656 channel_need_redraw = TRUE; | 1647 channel_need_redraw = TRUE; |
1657 } | 1648 } |
1658 | 1649 |
1659 /* | 1650 /* |
2412 cbq_T *cbhead, | 2403 cbq_T *cbhead, |
2413 cbq_T *item, | 2404 cbq_T *item, |
2414 typval_T *argv) | 2405 typval_T *argv) |
2415 { | 2406 { |
2416 ch_log(channel, "Invoking one-time callback %s", | 2407 ch_log(channel, "Invoking one-time callback %s", |
2417 (char *)item->cq_callback); | 2408 (char *)item->cq_callback.cb_name); |
2418 /* Remove the item from the list first, if the callback | 2409 /* Remove the item from the list first, if the callback |
2419 * invokes ch_close() the list will be cleared. */ | 2410 * invokes ch_close() the list will be cleared. */ |
2420 remove_cb_node(cbhead, item); | 2411 remove_cb_node(cbhead, item); |
2421 invoke_callback(channel, item->cq_callback, item->cq_partial, argv); | 2412 invoke_callback(channel, &item->cq_callback, argv); |
2422 free_callback(item->cq_callback, item->cq_partial); | 2413 free_callback(&item->cq_callback); |
2423 vim_free(item); | 2414 vim_free(item); |
2424 } | 2415 } |
2425 | 2416 |
2426 static void | 2417 static void |
2427 append_to_buffer(buf_T *buffer, char_u *msg, channel_T *channel, ch_part_T part) | 2418 append_to_buffer(buf_T *buffer, char_u *msg, channel_T *channel, ch_part_T part) |
2551 int seq_nr = -1; | 2542 int seq_nr = -1; |
2552 chanpart_T *ch_part = &channel->ch_part[part]; | 2543 chanpart_T *ch_part = &channel->ch_part[part]; |
2553 ch_mode_T ch_mode = ch_part->ch_mode; | 2544 ch_mode_T ch_mode = ch_part->ch_mode; |
2554 cbq_T *cbhead = &ch_part->ch_cb_head; | 2545 cbq_T *cbhead = &ch_part->ch_cb_head; |
2555 cbq_T *cbitem; | 2546 cbq_T *cbitem; |
2556 char_u *callback = NULL; | 2547 callback_T *callback = NULL; |
2557 partial_T *partial = NULL; | |
2558 buf_T *buffer = NULL; | 2548 buf_T *buffer = NULL; |
2559 char_u *p; | 2549 char_u *p; |
2560 | 2550 |
2561 if (channel->ch_nb_close_cb != NULL) | 2551 if (channel->ch_nb_close_cb != NULL) |
2562 /* this channel is handled elsewhere (netbeans) */ | 2552 /* this channel is handled elsewhere (netbeans) */ |
2565 /* Use a message-specific callback, part callback or channel callback */ | 2555 /* Use a message-specific callback, part callback or channel callback */ |
2566 for (cbitem = cbhead->cq_next; cbitem != NULL; cbitem = cbitem->cq_next) | 2556 for (cbitem = cbhead->cq_next; cbitem != NULL; cbitem = cbitem->cq_next) |
2567 if (cbitem->cq_seq_nr == 0) | 2557 if (cbitem->cq_seq_nr == 0) |
2568 break; | 2558 break; |
2569 if (cbitem != NULL) | 2559 if (cbitem != NULL) |
2570 { | 2560 callback = &cbitem->cq_callback; |
2571 callback = cbitem->cq_callback; | 2561 else if (ch_part->ch_callback.cb_name != NULL) |
2572 partial = cbitem->cq_partial; | 2562 callback = &ch_part->ch_callback; |
2573 } | 2563 else if (channel->ch_callback.cb_name != NULL) |
2574 else if (ch_part->ch_callback != NULL) | 2564 callback = &channel->ch_callback; |
2575 { | |
2576 callback = ch_part->ch_callback; | |
2577 partial = ch_part->ch_partial; | |
2578 } | |
2579 else | |
2580 { | |
2581 callback = channel->ch_callback; | |
2582 partial = channel->ch_partial; | |
2583 } | |
2584 | 2565 |
2585 buffer = ch_part->ch_bufref.br_buf; | 2566 buffer = ch_part->ch_bufref.br_buf; |
2586 if (buffer != NULL && (!bufref_valid(&ch_part->ch_bufref) | 2567 if (buffer != NULL && (!bufref_valid(&ch_part->ch_bufref) |
2587 || buffer->b_ml.ml_mfp == NULL)) | 2568 || buffer->b_ml.ml_mfp == NULL)) |
2588 { | 2569 { |
2640 /* If there is no callback or buffer drop the message. */ | 2621 /* If there is no callback or buffer drop the message. */ |
2641 if (callback == NULL && buffer == NULL) | 2622 if (callback == NULL && buffer == NULL) |
2642 { | 2623 { |
2643 /* If there is a close callback it may use ch_read() to get the | 2624 /* If there is a close callback it may use ch_read() to get the |
2644 * messages. */ | 2625 * messages. */ |
2645 if (channel->ch_close_cb == NULL && !channel->ch_drop_never) | 2626 if (channel->ch_close_cb.cb_name == NULL && !channel->ch_drop_never) |
2646 drop_messages(channel, part); | 2627 drop_messages(channel, part); |
2647 return FALSE; | 2628 return FALSE; |
2648 } | 2629 } |
2649 | 2630 |
2650 if (ch_mode == MODE_NL) | 2631 if (ch_mode == MODE_NL) |
2759 invoke_one_time_callback(channel, cbhead, cbitem, argv); | 2740 invoke_one_time_callback(channel, cbhead, cbitem, argv); |
2760 else | 2741 else |
2761 { | 2742 { |
2762 /* invoke the channel callback */ | 2743 /* invoke the channel callback */ |
2763 ch_log(channel, "Invoking channel callback %s", | 2744 ch_log(channel, "Invoking channel callback %s", |
2764 (char *)callback); | 2745 (char *)callback->cb_name); |
2765 invoke_callback(channel, callback, partial, argv); | 2746 invoke_callback(channel, callback, argv); |
2766 } | 2747 } |
2767 } | 2748 } |
2768 } | 2749 } |
2769 else | 2750 else |
2770 ch_log(channel, "Dropping message %d", seq_nr); | 2751 ch_log(channel, "Dropping message %d", seq_nr); |
2954 if (invoke_close_cb) | 2935 if (invoke_close_cb) |
2955 { | 2936 { |
2956 ch_part_T part; | 2937 ch_part_T part; |
2957 | 2938 |
2958 /* Invoke callbacks and flush buffers before the close callback. */ | 2939 /* Invoke callbacks and flush buffers before the close callback. */ |
2959 if (channel->ch_close_cb != NULL) | 2940 if (channel->ch_close_cb.cb_name != NULL) |
2960 ch_log(channel, | 2941 ch_log(channel, |
2961 "Invoking callbacks and flushing buffers before closing"); | 2942 "Invoking callbacks and flushing buffers before closing"); |
2962 for (part = PART_SOCK; part < PART_IN; ++part) | 2943 for (part = PART_SOCK; part < PART_IN; ++part) |
2963 { | 2944 { |
2964 if (channel->ch_close_cb != NULL | 2945 if (channel->ch_close_cb.cb_name != NULL |
2965 || channel->ch_part[part].ch_bufref.br_buf != NULL) | 2946 || channel->ch_part[part].ch_bufref.br_buf != NULL) |
2966 { | 2947 { |
2967 /* Increment the refcount to avoid the channel being freed | 2948 /* Increment the refcount to avoid the channel being freed |
2968 * halfway. */ | 2949 * halfway. */ |
2969 ++channel->ch_refcount; | 2950 ++channel->ch_refcount; |
2970 if (channel->ch_close_cb == NULL) | 2951 if (channel->ch_close_cb.cb_name == NULL) |
2971 ch_log(channel, "flushing %s buffers before closing", | 2952 ch_log(channel, "flushing %s buffers before closing", |
2972 part_names[part]); | 2953 part_names[part]); |
2973 while (may_invoke_callback(channel, part)) | 2954 while (may_invoke_callback(channel, part)) |
2974 ; | 2955 ; |
2975 --channel->ch_refcount; | 2956 --channel->ch_refcount; |
2976 } | 2957 } |
2977 } | 2958 } |
2978 | 2959 |
2979 if (channel->ch_close_cb != NULL) | 2960 if (channel->ch_close_cb.cb_name != NULL) |
2980 { | 2961 { |
2981 typval_T argv[1]; | 2962 typval_T argv[1]; |
2982 typval_T rettv; | 2963 typval_T rettv; |
2983 int dummy; | 2964 int dummy; |
2984 | 2965 |
2985 /* Increment the refcount to avoid the channel being freed | 2966 /* Increment the refcount to avoid the channel being freed |
2986 * halfway. */ | 2967 * halfway. */ |
2987 ++channel->ch_refcount; | 2968 ++channel->ch_refcount; |
2988 ch_log(channel, "Invoking close callback %s", | 2969 ch_log(channel, "Invoking close callback %s", |
2989 (char *)channel->ch_close_cb); | 2970 (char *)channel->ch_close_cb.cb_name); |
2990 argv[0].v_type = VAR_CHANNEL; | 2971 argv[0].v_type = VAR_CHANNEL; |
2991 argv[0].vval.v_channel = channel; | 2972 argv[0].vval.v_channel = channel; |
2992 call_func(channel->ch_close_cb, -1, | 2973 call_callback(&channel->ch_close_cb, -1, |
2993 &rettv, 1, argv, NULL, 0L, 0L, &dummy, TRUE, | 2974 &rettv, 1, argv, NULL, 0L, 0L, &dummy, TRUE, NULL); |
2994 channel->ch_close_partial, NULL); | |
2995 clear_tv(&rettv); | 2975 clear_tv(&rettv); |
2996 channel_need_redraw = TRUE; | 2976 channel_need_redraw = TRUE; |
2997 | 2977 |
2998 /* the callback is only called once */ | 2978 /* the callback is only called once */ |
2999 free_callback(channel->ch_close_cb, channel->ch_close_partial); | 2979 free_callback(&channel->ch_close_cb); |
3000 channel->ch_close_cb = NULL; | |
3001 channel->ch_close_partial = NULL; | |
3002 | 2980 |
3003 if (channel_need_redraw) | 2981 if (channel_need_redraw) |
3004 { | 2982 { |
3005 channel_need_redraw = FALSE; | 2983 channel_need_redraw = FALSE; |
3006 redraw_after_callback(TRUE); | 2984 redraw_after_callback(TRUE); |
3059 while (cb_head->cq_next != NULL) | 3037 while (cb_head->cq_next != NULL) |
3060 { | 3038 { |
3061 cbq_T *node = cb_head->cq_next; | 3039 cbq_T *node = cb_head->cq_next; |
3062 | 3040 |
3063 remove_cb_node(cb_head, node); | 3041 remove_cb_node(cb_head, node); |
3064 free_callback(node->cq_callback, node->cq_partial); | 3042 free_callback(&node->cq_callback); |
3065 vim_free(node); | 3043 vim_free(node); |
3066 } | 3044 } |
3067 | 3045 |
3068 while (json_head->jq_next != NULL) | 3046 while (json_head->jq_next != NULL) |
3069 { | 3047 { |
3070 free_tv(json_head->jq_next->jq_value); | 3048 free_tv(json_head->jq_next->jq_value); |
3071 remove_json_node(json_head, json_head->jq_next); | 3049 remove_json_node(json_head, json_head->jq_next); |
3072 } | 3050 } |
3073 | 3051 |
3074 free_callback(ch_part->ch_callback, ch_part->ch_partial); | 3052 free_callback(&ch_part->ch_callback); |
3075 ch_part->ch_callback = NULL; | |
3076 ch_part->ch_partial = NULL; | |
3077 | 3053 |
3078 while (ch_part->ch_writeque.wq_next != NULL) | 3054 while (ch_part->ch_writeque.wq_next != NULL) |
3079 remove_from_writeque(&ch_part->ch_writeque, | 3055 remove_from_writeque(&ch_part->ch_writeque, |
3080 ch_part->ch_writeque.wq_next); | 3056 ch_part->ch_writeque.wq_next); |
3081 } | 3057 } |
3090 VIM_CLEAR(channel->ch_hostname); | 3066 VIM_CLEAR(channel->ch_hostname); |
3091 channel_clear_one(channel, PART_SOCK); | 3067 channel_clear_one(channel, PART_SOCK); |
3092 channel_clear_one(channel, PART_OUT); | 3068 channel_clear_one(channel, PART_OUT); |
3093 channel_clear_one(channel, PART_ERR); | 3069 channel_clear_one(channel, PART_ERR); |
3094 channel_clear_one(channel, PART_IN); | 3070 channel_clear_one(channel, PART_IN); |
3095 free_callback(channel->ch_callback, channel->ch_partial); | 3071 free_callback(&channel->ch_callback); |
3096 channel->ch_callback = NULL; | 3072 free_callback(&channel->ch_close_cb); |
3097 channel->ch_partial = NULL; | |
3098 free_callback(channel->ch_close_cb, channel->ch_close_partial); | |
3099 channel->ch_close_cb = NULL; | |
3100 channel->ch_close_partial = NULL; | |
3101 } | 3073 } |
3102 | 3074 |
3103 #if defined(EXITFREE) || defined(PROTO) | 3075 #if defined(EXITFREE) || defined(PROTO) |
3104 void | 3076 void |
3105 channel_free_all(void) | 3077 channel_free_all(void) |
3989 return NULL; | 3961 return NULL; |
3990 | 3962 |
3991 /* Set the callback. An empty callback means no callback and not reading | 3963 /* Set the callback. An empty callback means no callback and not reading |
3992 * the response. With "ch_evalexpr()" and "ch_evalraw()" a callback is not | 3964 * the response. With "ch_evalexpr()" and "ch_evalraw()" a callback is not |
3993 * allowed. */ | 3965 * allowed. */ |
3994 if (opt->jo_callback != NULL && *opt->jo_callback != NUL) | 3966 if (opt->jo_callback.cb_name != NULL && *opt->jo_callback.cb_name != NUL) |
3995 { | 3967 { |
3996 if (eval) | 3968 if (eval) |
3997 { | 3969 { |
3998 semsg(_("E917: Cannot use a callback with %s()"), fun); | 3970 semsg(_("E917: Cannot use a callback with %s()"), fun); |
3999 return NULL; | 3971 return NULL; |
4000 } | 3972 } |
4001 channel_set_req_callback(channel, *part_read, | 3973 channel_set_req_callback(channel, *part_read, &opt->jo_callback, id); |
4002 opt->jo_callback, opt->jo_partial, id); | |
4003 } | 3974 } |
4004 | 3975 |
4005 if (channel_send(channel, part_send, text, len, fun) == OK | 3976 if (channel_send(channel, part_send, text, len, fun) == OK |
4006 && opt->jo_callback == NULL) | 3977 && opt->jo_callback.cb_name == NULL) |
4007 return channel; | 3978 return channel; |
4008 return NULL; | 3979 return NULL; |
4009 } | 3980 } |
4010 | 3981 |
4011 /* | 3982 /* |
4557 * Free any members of a jobopt_T. | 4528 * Free any members of a jobopt_T. |
4558 */ | 4529 */ |
4559 void | 4530 void |
4560 free_job_options(jobopt_T *opt) | 4531 free_job_options(jobopt_T *opt) |
4561 { | 4532 { |
4562 if (opt->jo_partial != NULL) | 4533 if (opt->jo_callback.cb_partial != NULL) |
4563 partial_unref(opt->jo_partial); | 4534 partial_unref(opt->jo_callback.cb_partial); |
4564 else if (opt->jo_callback != NULL) | 4535 else if (opt->jo_callback.cb_name != NULL) |
4565 func_unref(opt->jo_callback); | 4536 func_unref(opt->jo_callback.cb_name); |
4566 if (opt->jo_out_partial != NULL) | 4537 if (opt->jo_out_cb.cb_partial != NULL) |
4567 partial_unref(opt->jo_out_partial); | 4538 partial_unref(opt->jo_out_cb.cb_partial); |
4568 else if (opt->jo_out_cb != NULL) | 4539 else if (opt->jo_out_cb.cb_name != NULL) |
4569 func_unref(opt->jo_out_cb); | 4540 func_unref(opt->jo_out_cb.cb_name); |
4570 if (opt->jo_err_partial != NULL) | 4541 if (opt->jo_err_cb.cb_partial != NULL) |
4571 partial_unref(opt->jo_err_partial); | 4542 partial_unref(opt->jo_err_cb.cb_partial); |
4572 else if (opt->jo_err_cb != NULL) | 4543 else if (opt->jo_err_cb.cb_name != NULL) |
4573 func_unref(opt->jo_err_cb); | 4544 func_unref(opt->jo_err_cb.cb_name); |
4574 if (opt->jo_close_partial != NULL) | 4545 if (opt->jo_close_cb.cb_partial != NULL) |
4575 partial_unref(opt->jo_close_partial); | 4546 partial_unref(opt->jo_close_cb.cb_partial); |
4576 else if (opt->jo_close_cb != NULL) | 4547 else if (opt->jo_close_cb.cb_name != NULL) |
4577 func_unref(opt->jo_close_cb); | 4548 func_unref(opt->jo_close_cb.cb_name); |
4578 if (opt->jo_exit_partial != NULL) | 4549 if (opt->jo_exit_cb.cb_partial != NULL) |
4579 partial_unref(opt->jo_exit_partial); | 4550 partial_unref(opt->jo_exit_cb.cb_partial); |
4580 else if (opt->jo_exit_cb != NULL) | 4551 else if (opt->jo_exit_cb.cb_name != NULL) |
4581 func_unref(opt->jo_exit_cb); | 4552 func_unref(opt->jo_exit_cb.cb_name); |
4582 if (opt->jo_env != NULL) | 4553 if (opt->jo_env != NULL) |
4583 dict_unref(opt->jo_env); | 4554 dict_unref(opt->jo_env); |
4584 } | 4555 } |
4585 | 4556 |
4586 /* | 4557 /* |
4769 else if (STRCMP(hi->hi_key, "callback") == 0) | 4740 else if (STRCMP(hi->hi_key, "callback") == 0) |
4770 { | 4741 { |
4771 if (!(supported & JO_CALLBACK)) | 4742 if (!(supported & JO_CALLBACK)) |
4772 break; | 4743 break; |
4773 opt->jo_set |= JO_CALLBACK; | 4744 opt->jo_set |= JO_CALLBACK; |
4774 opt->jo_callback = get_callback(item, &opt->jo_partial); | 4745 opt->jo_callback = get_callback(item); |
4775 if (opt->jo_callback == NULL) | 4746 if (opt->jo_callback.cb_name == NULL) |
4776 { | 4747 { |
4777 semsg(_(e_invargval), "callback"); | 4748 semsg(_(e_invargval), "callback"); |
4778 return FAIL; | 4749 return FAIL; |
4779 } | 4750 } |
4780 } | 4751 } |
4781 else if (STRCMP(hi->hi_key, "out_cb") == 0) | 4752 else if (STRCMP(hi->hi_key, "out_cb") == 0) |
4782 { | 4753 { |
4783 if (!(supported & JO_OUT_CALLBACK)) | 4754 if (!(supported & JO_OUT_CALLBACK)) |
4784 break; | 4755 break; |
4785 opt->jo_set |= JO_OUT_CALLBACK; | 4756 opt->jo_set |= JO_OUT_CALLBACK; |
4786 opt->jo_out_cb = get_callback(item, &opt->jo_out_partial); | 4757 opt->jo_out_cb = get_callback(item); |
4787 if (opt->jo_out_cb == NULL) | 4758 if (opt->jo_out_cb.cb_name == NULL) |
4788 { | 4759 { |
4789 semsg(_(e_invargval), "out_cb"); | 4760 semsg(_(e_invargval), "out_cb"); |
4790 return FAIL; | 4761 return FAIL; |
4791 } | 4762 } |
4792 } | 4763 } |
4793 else if (STRCMP(hi->hi_key, "err_cb") == 0) | 4764 else if (STRCMP(hi->hi_key, "err_cb") == 0) |
4794 { | 4765 { |
4795 if (!(supported & JO_ERR_CALLBACK)) | 4766 if (!(supported & JO_ERR_CALLBACK)) |
4796 break; | 4767 break; |
4797 opt->jo_set |= JO_ERR_CALLBACK; | 4768 opt->jo_set |= JO_ERR_CALLBACK; |
4798 opt->jo_err_cb = get_callback(item, &opt->jo_err_partial); | 4769 opt->jo_err_cb = get_callback(item); |
4799 if (opt->jo_err_cb == NULL) | 4770 if (opt->jo_err_cb.cb_name == NULL) |
4800 { | 4771 { |
4801 semsg(_(e_invargval), "err_cb"); | 4772 semsg(_(e_invargval), "err_cb"); |
4802 return FAIL; | 4773 return FAIL; |
4803 } | 4774 } |
4804 } | 4775 } |
4805 else if (STRCMP(hi->hi_key, "close_cb") == 0) | 4776 else if (STRCMP(hi->hi_key, "close_cb") == 0) |
4806 { | 4777 { |
4807 if (!(supported & JO_CLOSE_CALLBACK)) | 4778 if (!(supported & JO_CLOSE_CALLBACK)) |
4808 break; | 4779 break; |
4809 opt->jo_set |= JO_CLOSE_CALLBACK; | 4780 opt->jo_set |= JO_CLOSE_CALLBACK; |
4810 opt->jo_close_cb = get_callback(item, &opt->jo_close_partial); | 4781 opt->jo_close_cb = get_callback(item); |
4811 if (opt->jo_close_cb == NULL) | 4782 if (opt->jo_close_cb.cb_name == NULL) |
4812 { | 4783 { |
4813 semsg(_(e_invargval), "close_cb"); | 4784 semsg(_(e_invargval), "close_cb"); |
4814 return FAIL; | 4785 return FAIL; |
4815 } | 4786 } |
4816 } | 4787 } |
4831 else if (STRCMP(hi->hi_key, "exit_cb") == 0) | 4802 else if (STRCMP(hi->hi_key, "exit_cb") == 0) |
4832 { | 4803 { |
4833 if (!(supported & JO_EXIT_CB)) | 4804 if (!(supported & JO_EXIT_CB)) |
4834 break; | 4805 break; |
4835 opt->jo_set |= JO_EXIT_CB; | 4806 opt->jo_set |= JO_EXIT_CB; |
4836 opt->jo_exit_cb = get_callback(item, &opt->jo_exit_partial); | 4807 opt->jo_exit_cb = get_callback(item); |
4837 if (opt->jo_exit_cb == NULL) | 4808 if (opt->jo_exit_cb.cb_name == NULL) |
4838 { | 4809 { |
4839 semsg(_(e_invargval), "exit_cb"); | 4810 semsg(_(e_invargval), "exit_cb"); |
4840 return FAIL; | 4811 return FAIL; |
4841 } | 4812 } |
4842 } | 4813 } |
5199 vim_free(job->jv_termsig); | 5170 vim_free(job->jv_termsig); |
5200 #endif | 5171 #endif |
5201 #ifdef MSWIN | 5172 #ifdef MSWIN |
5202 vim_free(job->jv_tty_type); | 5173 vim_free(job->jv_tty_type); |
5203 #endif | 5174 #endif |
5204 free_callback(job->jv_exit_cb, job->jv_exit_partial); | 5175 free_callback(&job->jv_exit_cb); |
5205 if (job->jv_argv != NULL) | 5176 if (job->jv_argv != NULL) |
5206 { | 5177 { |
5207 for (i = 0; job->jv_argv[i] != NULL; i++) | 5178 for (i = 0; job->jv_argv[i] != NULL; i++) |
5208 vim_free(job->jv_argv[i]); | 5179 vim_free(job->jv_argv[i]); |
5209 vim_free(job->jv_argv); | 5180 vim_free(job->jv_argv); |
5287 */ | 5258 */ |
5288 static int | 5259 static int |
5289 job_need_end_check(job_T *job) | 5260 job_need_end_check(job_T *job) |
5290 { | 5261 { |
5291 return job->jv_status == JOB_STARTED | 5262 return job->jv_status == JOB_STARTED |
5292 && (job->jv_stoponexit != NULL || job->jv_exit_cb != NULL); | 5263 && (job->jv_stoponexit != NULL || job->jv_exit_cb.cb_name != NULL); |
5293 } | 5264 } |
5294 | 5265 |
5295 /* | 5266 /* |
5296 * Return TRUE if the channel of "job" is still useful. | 5267 * Return TRUE if the channel of "job" is still useful. |
5297 */ | 5268 */ |
5463 | 5434 |
5464 /* When only channel-in is kept open, close explicitly. */ | 5435 /* When only channel-in is kept open, close explicitly. */ |
5465 if (job->jv_channel != NULL) | 5436 if (job->jv_channel != NULL) |
5466 ch_close_part(job->jv_channel, PART_IN); | 5437 ch_close_part(job->jv_channel, PART_IN); |
5467 | 5438 |
5468 if (job->jv_exit_cb != NULL) | 5439 if (job->jv_exit_cb.cb_name != NULL) |
5469 { | 5440 { |
5470 typval_T argv[3]; | 5441 typval_T argv[3]; |
5471 typval_T rettv; | 5442 typval_T rettv; |
5472 int dummy; | 5443 int dummy; |
5473 | 5444 |
5474 /* Invoke the exit callback. Make sure the refcount is > 0. */ | 5445 /* Invoke the exit callback. Make sure the refcount is > 0. */ |
5475 ch_log(job->jv_channel, "Invoking exit callback %s", job->jv_exit_cb); | 5446 ch_log(job->jv_channel, "Invoking exit callback %s", |
5447 job->jv_exit_cb.cb_name); | |
5476 ++job->jv_refcount; | 5448 ++job->jv_refcount; |
5477 argv[0].v_type = VAR_JOB; | 5449 argv[0].v_type = VAR_JOB; |
5478 argv[0].vval.v_job = job; | 5450 argv[0].vval.v_job = job; |
5479 argv[1].v_type = VAR_NUMBER; | 5451 argv[1].v_type = VAR_NUMBER; |
5480 argv[1].vval.v_number = job->jv_exitval; | 5452 argv[1].vval.v_number = job->jv_exitval; |
5481 call_func(job->jv_exit_cb, -1, | 5453 call_callback(&job->jv_exit_cb, -1, |
5482 &rettv, 2, argv, NULL, 0L, 0L, &dummy, TRUE, | 5454 &rettv, 2, argv, NULL, 0L, 0L, &dummy, TRUE, NULL); |
5483 job->jv_exit_partial, NULL); | |
5484 clear_tv(&rettv); | 5455 clear_tv(&rettv); |
5485 --job->jv_refcount; | 5456 --job->jv_refcount; |
5486 channel_need_redraw = TRUE; | 5457 channel_need_redraw = TRUE; |
5487 } | 5458 } |
5488 | 5459 |
5620 else | 5591 else |
5621 job->jv_stoponexit = vim_strsave(opt->jo_stoponexit); | 5592 job->jv_stoponexit = vim_strsave(opt->jo_stoponexit); |
5622 } | 5593 } |
5623 if (opt->jo_set & JO_EXIT_CB) | 5594 if (opt->jo_set & JO_EXIT_CB) |
5624 { | 5595 { |
5625 free_callback(job->jv_exit_cb, job->jv_exit_partial); | 5596 free_callback(&job->jv_exit_cb); |
5626 if (opt->jo_exit_cb == NULL || *opt->jo_exit_cb == NUL) | 5597 if (opt->jo_exit_cb.cb_name == NULL || *opt->jo_exit_cb.cb_name == NUL) |
5627 { | 5598 { |
5628 job->jv_exit_cb = NULL; | 5599 job->jv_exit_cb.cb_name = NULL; |
5629 job->jv_exit_partial = NULL; | 5600 job->jv_exit_cb.cb_partial = NULL; |
5630 } | 5601 } |
5631 else | 5602 else |
5632 { | 5603 copy_callback(&job->jv_exit_cb, &opt->jo_exit_cb); |
5633 job->jv_exit_partial = opt->jo_exit_partial; | |
5634 if (job->jv_exit_partial != NULL) | |
5635 { | |
5636 job->jv_exit_cb = opt->jo_exit_cb; | |
5637 ++job->jv_exit_partial->pt_refcount; | |
5638 } | |
5639 else | |
5640 { | |
5641 job->jv_exit_cb = vim_strsave(opt->jo_exit_cb); | |
5642 func_ref(job->jv_exit_cb); | |
5643 } | |
5644 } | |
5645 } | 5604 } |
5646 } | 5605 } |
5647 | 5606 |
5648 /* | 5607 /* |
5649 * Called when Vim is exiting: kill all jobs that have the "stoponexit" flag. | 5608 * Called when Vim is exiting: kill all jobs that have the "stoponexit" flag. |
5957 dict_add_number(dict, "process", nr); | 5916 dict_add_number(dict, "process", nr); |
5958 dict_add_string(dict, "tty_in", job->jv_tty_in); | 5917 dict_add_string(dict, "tty_in", job->jv_tty_in); |
5959 dict_add_string(dict, "tty_out", job->jv_tty_out); | 5918 dict_add_string(dict, "tty_out", job->jv_tty_out); |
5960 | 5919 |
5961 dict_add_number(dict, "exitval", job->jv_exitval); | 5920 dict_add_number(dict, "exitval", job->jv_exitval); |
5962 dict_add_string(dict, "exit_cb", job->jv_exit_cb); | 5921 dict_add_string(dict, "exit_cb", job->jv_exit_cb.cb_name); |
5963 dict_add_string(dict, "stoponexit", job->jv_stoponexit); | 5922 dict_add_string(dict, "stoponexit", job->jv_stoponexit); |
5964 #ifdef UNIX | 5923 #ifdef UNIX |
5965 dict_add_string(dict, "termsig", job->jv_termsig); | 5924 dict_add_string(dict, "termsig", job->jv_termsig); |
5966 #endif | 5925 #endif |
5967 #ifdef MSWIN | 5926 #ifdef MSWIN |
6057 // text can always be inserted above the last line. | 6016 // text can always be inserted above the last line. |
6058 ml_append(lnum, (char_u *)"", 0, FALSE); | 6017 ml_append(lnum, (char_u *)"", 0, FALSE); |
6059 curwin->w_cursor.lnum = lnum + 1; | 6018 curwin->w_cursor.lnum = lnum + 1; |
6060 curwin->w_cursor.col = 0; | 6019 curwin->w_cursor.col = 0; |
6061 | 6020 |
6062 if (curbuf->b_prompt_callback == NULL || *curbuf->b_prompt_callback == NUL) | 6021 if (curbuf->b_prompt_callback.cb_name == NULL |
6022 || *curbuf->b_prompt_callback.cb_name == NUL) | |
6063 return; | 6023 return; |
6064 text = ml_get(lnum); | 6024 text = ml_get(lnum); |
6065 prompt = prompt_text(); | 6025 prompt = prompt_text(); |
6066 if (STRLEN(text) >= STRLEN(prompt)) | 6026 if (STRLEN(text) >= STRLEN(prompt)) |
6067 text += STRLEN(prompt); | 6027 text += STRLEN(prompt); |
6068 argv[0].v_type = VAR_STRING; | 6028 argv[0].v_type = VAR_STRING; |
6069 argv[0].vval.v_string = vim_strsave(text); | 6029 argv[0].vval.v_string = vim_strsave(text); |
6070 argv[1].v_type = VAR_UNKNOWN; | 6030 argv[1].v_type = VAR_UNKNOWN; |
6071 | 6031 |
6072 call_func(curbuf->b_prompt_callback, -1, | 6032 call_callback(&curbuf->b_prompt_callback, -1, |
6073 &rettv, 1, argv, NULL, 0L, 0L, &dummy, TRUE, | 6033 &rettv, 1, argv, NULL, 0L, 0L, &dummy, TRUE, NULL); |
6074 curbuf->b_prompt_partial, NULL); | |
6075 clear_tv(&argv[0]); | 6034 clear_tv(&argv[0]); |
6076 clear_tv(&rettv); | 6035 clear_tv(&rettv); |
6077 } | 6036 } |
6078 | 6037 |
6079 /* | 6038 /* |
6084 { | 6043 { |
6085 typval_T rettv; | 6044 typval_T rettv; |
6086 int dummy; | 6045 int dummy; |
6087 typval_T argv[1]; | 6046 typval_T argv[1]; |
6088 | 6047 |
6089 if (curbuf->b_prompt_interrupt == NULL | 6048 if (curbuf->b_prompt_interrupt.cb_name == NULL |
6090 || *curbuf->b_prompt_interrupt == NUL) | 6049 || *curbuf->b_prompt_interrupt.cb_name == NUL) |
6091 return FALSE; | 6050 return FALSE; |
6092 argv[0].v_type = VAR_UNKNOWN; | 6051 argv[0].v_type = VAR_UNKNOWN; |
6093 | 6052 |
6094 got_int = FALSE; // don't skip executing commands | 6053 got_int = FALSE; // don't skip executing commands |
6095 call_func(curbuf->b_prompt_interrupt, -1, | 6054 call_callback(&curbuf->b_prompt_interrupt, -1, |
6096 &rettv, 0, argv, NULL, 0L, 0L, &dummy, TRUE, | 6055 &rettv, 0, argv, NULL, 0L, 0L, &dummy, TRUE, NULL); |
6097 curbuf->b_prompt_int_partial, NULL); | |
6098 clear_tv(&rettv); | 6056 clear_tv(&rettv); |
6099 return TRUE; | 6057 return TRUE; |
6100 } | 6058 } |
6101 | 6059 |
6102 #endif /* FEAT_JOB_CHANNEL */ | 6060 #endif /* FEAT_JOB_CHANNEL */ |