• R/O
  • SSH

vim: Commit

Mirror of the Vim source from https://github.com/vim/vim


Commit MetaInfo

Revision966f1213dd35ffd7cd1fc949988b159f616701b2 (tree)
Time2023-01-11 21:00:05
AuthorBram Moolenaar <Bram@vim....>
CommiterBram Moolenaar

Log Message

patch 9.0.1175: the set_ref_in_item() function is too long

Commit: https://github.com/vim/vim/commit/ea125393af01ecaf75cee8e085a57f8143f3ae3e
Author: Yegappan Lakshmanan <yegappan@yahoo.com>
Date: Wed Jan 11 11:46:17 2023 +0000

patch 9.0.1175: the set_ref_in_item() function is too long
Problem: The set_ref_in_item() function is too long.
Solution: Use a separate function for more complicated types. (Yegappan
Lakshmanan, closes #11802)

Change Summary

Incremental Difference

diff -r 2ed7c3993447 -r 966f1213dd35 src/eval.c
--- a/src/eval.c Tue Jan 10 21:00:04 2023 +0100
+++ b/src/eval.c Wed Jan 11 13:00:05 2023 +0100
@@ -5484,6 +5484,255 @@
54845484 }
54855485
54865486 /*
5487+ * Mark the dict "dd" with "copyID".
5488+ * Also see set_ref_in_item().
5489+ */
5490+ static int
5491+set_ref_in_item_dict(
5492+ dict_T *dd,
5493+ int copyID,
5494+ ht_stack_T **ht_stack,
5495+ list_stack_T **list_stack)
5496+{
5497+ if (dd == NULL || dd->dv_copyID == copyID)
5498+ return FALSE;
5499+
5500+ // Didn't see this dict yet.
5501+ dd->dv_copyID = copyID;
5502+ if (ht_stack == NULL)
5503+ return set_ref_in_ht(&dd->dv_hashtab, copyID, list_stack);
5504+
5505+ ht_stack_T *newitem = ALLOC_ONE(ht_stack_T);
5506+ if (newitem == NULL)
5507+ return TRUE;
5508+
5509+ newitem->ht = &dd->dv_hashtab;
5510+ newitem->prev = *ht_stack;
5511+ *ht_stack = newitem;
5512+
5513+ return FALSE;
5514+}
5515+
5516+/*
5517+ * Mark the list "ll" with "copyID".
5518+ * Also see set_ref_in_item().
5519+ */
5520+ static int
5521+set_ref_in_item_list(
5522+ list_T *ll,
5523+ int copyID,
5524+ ht_stack_T **ht_stack,
5525+ list_stack_T **list_stack)
5526+{
5527+ if (ll == NULL || ll->lv_copyID == copyID)
5528+ return FALSE;
5529+
5530+ // Didn't see this list yet.
5531+ ll->lv_copyID = copyID;
5532+ if (list_stack == NULL)
5533+ return set_ref_in_list_items(ll, copyID, ht_stack);
5534+
5535+ list_stack_T *newitem = ALLOC_ONE(list_stack_T);
5536+ if (newitem == NULL)
5537+ return TRUE;
5538+
5539+ newitem->list = ll;
5540+ newitem->prev = *list_stack;
5541+ *list_stack = newitem;
5542+
5543+ return FALSE;
5544+}
5545+
5546+/*
5547+ * Mark the partial "pt" with "copyID".
5548+ * Also see set_ref_in_item().
5549+ */
5550+ static int
5551+set_ref_in_item_partial(
5552+ partial_T *pt,
5553+ int copyID,
5554+ ht_stack_T **ht_stack,
5555+ list_stack_T **list_stack)
5556+{
5557+ if (pt == NULL || pt->pt_copyID == copyID)
5558+ return FALSE;
5559+
5560+ // Didn't see this partial yet.
5561+ pt->pt_copyID = copyID;
5562+
5563+ int abort = set_ref_in_func(pt->pt_name, pt->pt_func, copyID);
5564+
5565+ if (pt->pt_dict != NULL)
5566+ {
5567+ typval_T dtv;
5568+
5569+ dtv.v_type = VAR_DICT;
5570+ dtv.vval.v_dict = pt->pt_dict;
5571+ set_ref_in_item(&dtv, copyID, ht_stack, list_stack);
5572+ }
5573+
5574+ for (int i = 0; i < pt->pt_argc; ++i)
5575+ abort = abort || set_ref_in_item(&pt->pt_argv[i], copyID,
5576+ ht_stack, list_stack);
5577+ // pt_funcstack is handled in set_ref_in_funcstacks()
5578+ // pt_loopvars is handled in set_ref_in_loopvars()
5579+
5580+ return abort;
5581+}
5582+
5583+/*
5584+ * Mark the job "pt" with "copyID".
5585+ * Also see set_ref_in_item().
5586+ */
5587+ static int
5588+set_ref_in_item_job(
5589+ job_T *job,
5590+ int copyID,
5591+ ht_stack_T **ht_stack,
5592+ list_stack_T **list_stack)
5593+{
5594+#ifdef FEAT_JOB_CHANNEL
5595+ typval_T dtv;
5596+
5597+ if (job == NULL || job->jv_copyID == copyID)
5598+ return FALSE;
5599+
5600+ job->jv_copyID = copyID;
5601+ if (job->jv_channel != NULL)
5602+ {
5603+ dtv.v_type = VAR_CHANNEL;
5604+ dtv.vval.v_channel = job->jv_channel;
5605+ set_ref_in_item(&dtv, copyID, ht_stack, list_stack);
5606+ }
5607+ if (job->jv_exit_cb.cb_partial != NULL)
5608+ {
5609+ dtv.v_type = VAR_PARTIAL;
5610+ dtv.vval.v_partial = job->jv_exit_cb.cb_partial;
5611+ set_ref_in_item(&dtv, copyID, ht_stack, list_stack);
5612+ }
5613+#endif
5614+
5615+ return FALSE;
5616+}
5617+
5618+/*
5619+ * Mark the channel "ch" with "copyID".
5620+ * Also see set_ref_in_item().
5621+ */
5622+ static int
5623+set_ref_in_item_channel(
5624+ channel_T *ch,
5625+ int copyID,
5626+ ht_stack_T **ht_stack,
5627+ list_stack_T **list_stack)
5628+{
5629+#ifdef FEAT_JOB_CHANNEL
5630+ typval_T dtv;
5631+
5632+ if (ch == NULL || ch->ch_copyID == copyID)
5633+ return FALSE;
5634+
5635+ ch->ch_copyID = copyID;
5636+ for (ch_part_T part = PART_SOCK; part < PART_COUNT; ++part)
5637+ {
5638+ for (jsonq_T *jq = ch->ch_part[part].ch_json_head.jq_next;
5639+ jq != NULL; jq = jq->jq_next)
5640+ set_ref_in_item(jq->jq_value, copyID, ht_stack, list_stack);
5641+ for (cbq_T *cq = ch->ch_part[part].ch_cb_head.cq_next; cq != NULL;
5642+ cq = cq->cq_next)
5643+ if (cq->cq_callback.cb_partial != NULL)
5644+ {
5645+ dtv.v_type = VAR_PARTIAL;
5646+ dtv.vval.v_partial = cq->cq_callback.cb_partial;
5647+ set_ref_in_item(&dtv, copyID, ht_stack, list_stack);
5648+ }
5649+ if (ch->ch_part[part].ch_callback.cb_partial != NULL)
5650+ {
5651+ dtv.v_type = VAR_PARTIAL;
5652+ dtv.vval.v_partial = ch->ch_part[part].ch_callback.cb_partial;
5653+ set_ref_in_item(&dtv, copyID, ht_stack, list_stack);
5654+ }
5655+ }
5656+ if (ch->ch_callback.cb_partial != NULL)
5657+ {
5658+ dtv.v_type = VAR_PARTIAL;
5659+ dtv.vval.v_partial = ch->ch_callback.cb_partial;
5660+ set_ref_in_item(&dtv, copyID, ht_stack, list_stack);
5661+ }
5662+ if (ch->ch_close_cb.cb_partial != NULL)
5663+ {
5664+ dtv.v_type = VAR_PARTIAL;
5665+ dtv.vval.v_partial = ch->ch_close_cb.cb_partial;
5666+ set_ref_in_item(&dtv, copyID, ht_stack, list_stack);
5667+ }
5668+#endif
5669+
5670+ return FALSE;
5671+}
5672+
5673+/*
5674+ * Mark the class "cl" with "copyID".
5675+ * Also see set_ref_in_item().
5676+ */
5677+ static int
5678+set_ref_in_item_class(
5679+ class_T *cl,
5680+ int copyID,
5681+ ht_stack_T **ht_stack,
5682+ list_stack_T **list_stack)
5683+{
5684+ int abort = FALSE;
5685+
5686+ if (cl == NULL || cl->class_copyID == copyID
5687+ || (cl->class_flags & CLASS_INTERFACE) != 0)
5688+ return FALSE;
5689+
5690+ cl->class_copyID = copyID;
5691+ for (int i = 0; !abort && i < cl->class_class_member_count; ++i)
5692+ abort = abort || set_ref_in_item(
5693+ &cl->class_members_tv[i],
5694+ copyID, ht_stack, list_stack);
5695+
5696+ for (int i = 0; !abort && i < cl->class_class_function_count; ++i)
5697+ abort = abort || set_ref_in_func(NULL,
5698+ cl->class_class_functions[i], copyID);
5699+
5700+ for (int i = 0; !abort && i < cl->class_obj_method_count; ++i)
5701+ abort = abort || set_ref_in_func(NULL,
5702+ cl->class_obj_methods[i], copyID);
5703+
5704+ return abort;
5705+}
5706+
5707+/*
5708+ * Mark the object "cl" with "copyID".
5709+ * Also see set_ref_in_item().
5710+ */
5711+ static int
5712+set_ref_in_item_object(
5713+ object_T *obj,
5714+ int copyID,
5715+ ht_stack_T **ht_stack,
5716+ list_stack_T **list_stack)
5717+{
5718+ int abort = FALSE;
5719+
5720+ if (obj == NULL || obj->obj_copyID == copyID)
5721+ return FALSE;
5722+
5723+ obj->obj_copyID = copyID;
5724+
5725+ // The typval_T array is right after the object_T.
5726+ typval_T *mtv = (typval_T *)(obj + 1);
5727+ for (int i = 0; !abort
5728+ && i < obj->obj_class->class_obj_member_count; ++i)
5729+ abort = abort || set_ref_in_item(mtv + i, copyID,
5730+ ht_stack, list_stack);
5731+
5732+ return abort;
5733+}
5734+
5735+/*
54875736 * Mark all lists, dicts and other container types referenced through typval
54885737 * "tv" with "copyID".
54895738 * "list_stack" is used to add lists to be marked. Can be NULL.
@@ -5503,62 +5752,12 @@
55035752 switch (tv->v_type)
55045753 {
55055754 case VAR_DICT:
5506- {
5507- dict_T *dd = tv->vval.v_dict;
5508-
5509- if (dd != NULL && dd->dv_copyID != copyID)
5510- {
5511- // Didn't see this dict yet.
5512- dd->dv_copyID = copyID;
5513- if (ht_stack == NULL)
5514- {
5515- abort = set_ref_in_ht(&dd->dv_hashtab, copyID, list_stack);
5516- }
5517- else
5518- {
5519- ht_stack_T *newitem = ALLOC_ONE(ht_stack_T);
5520-
5521- if (newitem == NULL)
5522- abort = TRUE;
5523- else
5524- {
5525- newitem->ht = &dd->dv_hashtab;
5526- newitem->prev = *ht_stack;
5527- *ht_stack = newitem;
5528- }
5529- }
5530- }
5531- break;
5532- }
5755+ return set_ref_in_item_dict(tv->vval.v_dict, copyID,
5756+ ht_stack, list_stack);
55335757
55345758 case VAR_LIST:
5535- {
5536- list_T *ll = tv->vval.v_list;
5537-
5538- if (ll != NULL && ll->lv_copyID != copyID)
5539- {
5540- // Didn't see this list yet.
5541- ll->lv_copyID = copyID;
5542- if (list_stack == NULL)
5543- {
5544- abort = set_ref_in_list_items(ll, copyID, ht_stack);
5545- }
5546- else
5547- {
5548- list_stack_T *newitem = ALLOC_ONE(list_stack_T);
5549-
5550- if (newitem == NULL)
5551- abort = TRUE;
5552- else
5553- {
5554- newitem->list = ll;
5555- newitem->prev = *list_stack;
5556- *list_stack = newitem;
5557- }
5558- }
5559- }
5560- break;
5561- }
5759+ return set_ref_in_item_list(tv->vval.v_list, copyID,
5760+ ht_stack, list_stack);
55625761
55635762 case VAR_FUNC:
55645763 {
@@ -5567,157 +5766,24 @@
55675766 }
55685767
55695768 case VAR_PARTIAL:
5570- {
5571- partial_T *pt = tv->vval.v_partial;
5572- int i;
5573-
5574- if (pt != NULL && pt->pt_copyID != copyID)
5575- {
5576- // Didn't see this partial yet.
5577- pt->pt_copyID = copyID;
5578-
5579- abort = set_ref_in_func(pt->pt_name, pt->pt_func, copyID);
5580-
5581- if (pt->pt_dict != NULL)
5582- {
5583- typval_T dtv;
5584-
5585- dtv.v_type = VAR_DICT;
5586- dtv.vval.v_dict = pt->pt_dict;
5587- set_ref_in_item(&dtv, copyID, ht_stack, list_stack);
5588- }
5589-
5590- for (i = 0; i < pt->pt_argc; ++i)
5591- abort = abort || set_ref_in_item(&pt->pt_argv[i], copyID,
5592- ht_stack, list_stack);
5593- // pt_funcstack is handled in set_ref_in_funcstacks()
5594- // pt_loopvars is handled in set_ref_in_loopvars()
5595- }
5596- break;
5597- }
5769+ return set_ref_in_item_partial(tv->vval.v_partial, copyID,
5770+ ht_stack, list_stack);
55985771
55995772 case VAR_JOB:
5600- {
5601-#ifdef FEAT_JOB_CHANNEL
5602- job_T *job = tv->vval.v_job;
5603- typval_T dtv;
5604-
5605- if (job != NULL && job->jv_copyID != copyID)
5606- {
5607- job->jv_copyID = copyID;
5608- if (job->jv_channel != NULL)
5609- {
5610- dtv.v_type = VAR_CHANNEL;
5611- dtv.vval.v_channel = job->jv_channel;
5612- set_ref_in_item(&dtv, copyID, ht_stack, list_stack);
5613- }
5614- if (job->jv_exit_cb.cb_partial != NULL)
5615- {
5616- dtv.v_type = VAR_PARTIAL;
5617- dtv.vval.v_partial = job->jv_exit_cb.cb_partial;
5618- set_ref_in_item(&dtv, copyID, ht_stack, list_stack);
5619- }
5620- }
5621-#endif
5622- break;
5623- }
5773+ return set_ref_in_item_job(tv->vval.v_job, copyID,
5774+ ht_stack, list_stack);
56245775
56255776 case VAR_CHANNEL:
5626- {
5627-#ifdef FEAT_JOB_CHANNEL
5628- channel_T *ch = tv->vval.v_channel;
5629- ch_part_T part;
5630- typval_T dtv;
5631- jsonq_T *jq;
5632- cbq_T *cq;
5633-
5634- if (ch != NULL && ch->ch_copyID != copyID)
5635- {
5636- ch->ch_copyID = copyID;
5637- for (part = PART_SOCK; part < PART_COUNT; ++part)
5638- {
5639- for (jq = ch->ch_part[part].ch_json_head.jq_next;
5640- jq != NULL; jq = jq->jq_next)
5641- set_ref_in_item(jq->jq_value, copyID,
5777+ return set_ref_in_item_channel(tv->vval.v_channel, copyID,
56425778 ht_stack, list_stack);
5643- for (cq = ch->ch_part[part].ch_cb_head.cq_next; cq != NULL;
5644- cq = cq->cq_next)
5645- if (cq->cq_callback.cb_partial != NULL)
5646- {
5647- dtv.v_type = VAR_PARTIAL;
5648- dtv.vval.v_partial = cq->cq_callback.cb_partial;
5649- set_ref_in_item(&dtv, copyID, ht_stack, list_stack);
5650- }
5651- if (ch->ch_part[part].ch_callback.cb_partial != NULL)
5652- {
5653- dtv.v_type = VAR_PARTIAL;
5654- dtv.vval.v_partial =
5655- ch->ch_part[part].ch_callback.cb_partial;
5656- set_ref_in_item(&dtv, copyID, ht_stack, list_stack);
5657- }
5658- }
5659- if (ch->ch_callback.cb_partial != NULL)
5660- {
5661- dtv.v_type = VAR_PARTIAL;
5662- dtv.vval.v_partial = ch->ch_callback.cb_partial;
5663- set_ref_in_item(&dtv, copyID, ht_stack, list_stack);
5664- }
5665- if (ch->ch_close_cb.cb_partial != NULL)
5666- {
5667- dtv.v_type = VAR_PARTIAL;
5668- dtv.vval.v_partial = ch->ch_close_cb.cb_partial;
5669- set_ref_in_item(&dtv, copyID, ht_stack, list_stack);
5670- }
5671- }
5672-#endif
5673- break;
5674- }
56755779
56765780 case VAR_CLASS:
5677- {
5678- class_T *cl = tv->vval.v_class;
5679- if (cl != NULL && cl->class_copyID != copyID
5680- && (cl->class_flags && CLASS_INTERFACE) == 0)
5681- {
5682- cl->class_copyID = copyID;
5683- for (int i = 0; !abort
5684- && i < cl->class_class_member_count; ++i)
5685- abort = abort || set_ref_in_item(
5686- &cl->class_members_tv[i],
5687- copyID, ht_stack, list_stack);
5688-
5689-
5690- for (int i = 0; !abort
5691- && i < cl->class_class_function_count; ++i)
5692- abort = abort || set_ref_in_func(NULL,
5693- cl->class_class_functions[i], copyID);
5694-
5695- for (int i = 0; !abort
5696- && i < cl->class_obj_method_count; ++i)
5697- abort = abort || set_ref_in_func(NULL,
5698- cl->class_obj_methods[i], copyID);
5699-
5700- // Mark initializer expressions?
5701- }
5702- break;
5703- }
5781+ return set_ref_in_item_class(tv->vval.v_class, copyID,
5782+ ht_stack, list_stack);
57045783
57055784 case VAR_OBJECT:
5706- {
5707- object_T *obj = tv->vval.v_object;
5708- if (obj != NULL && obj->obj_copyID != copyID)
5709- {
5710- obj->obj_copyID = copyID;
5711-
5712- // The typval_T array is right after the object_T.
5713- typval_T *mtv = (typval_T *)(obj + 1);
5714- for (int i = 0; !abort
5715- && i < obj->obj_class->class_obj_member_count; ++i)
5716- abort = abort || set_ref_in_item(mtv + i, copyID,
5785+ return set_ref_in_item_object(tv->vval.v_object, copyID,
57175786 ht_stack, list_stack);
5718- }
5719- break;
5720- }
57215787
57225788 case VAR_UNKNOWN:
57235789 case VAR_ANY:
diff -r 2ed7c3993447 -r 966f1213dd35 src/version.c
--- a/src/version.c Tue Jan 10 21:00:04 2023 +0100
+++ b/src/version.c Wed Jan 11 13:00:05 2023 +0100
@@ -696,6 +696,8 @@
696696 static int included_patches[] =
697697 { /* Add new patch number below this line */
698698 /**/
699+ 1175,
700+/**/
699701 1174,
700702 /**/
701703 1173,
Show on old repository browser