patch 8.0.1023: it is not easy to identify a quickfix list

Problem:    It is not easy to identify a quickfix list.
Solution:   Add the "id" field. (Yegappan Lakshmanan)
diff --git a/src/quickfix.c b/src/quickfix.c
index 71270d9..8277b93 100644
--- a/src/quickfix.c
+++ b/src/quickfix.c
@@ -58,6 +58,7 @@
  */
 typedef struct qf_list_S
 {
+    int_u	qf_id;		/* Unique identifier for this list */
     qfline_T	*qf_start;	/* pointer to the first error */
     qfline_T	*qf_last;	/* pointer to the last error */
     qfline_T	*qf_ptr;	/* pointer to the current error */
@@ -96,6 +97,7 @@
 };
 
 static qf_info_T ql_info;	/* global quickfix list */
+static int_u last_qf_id = 0;	/* Last used quickfix list id */
 
 #define FMT_PATTERNS 10		/* maximum number of % recognized */
 
@@ -1399,6 +1401,7 @@
 	qi->qf_curlist = qi->qf_listcount++;
     vim_memset(&qi->qf_lists[qi->qf_curlist], 0, (size_t)(sizeof(qf_list_T)));
     qf_store_title(qi, qi->qf_curlist, qf_title);
+    qi->qf_lists[qi->qf_curlist].qf_id = ++last_qf_id;
 }
 
 /*
@@ -1672,6 +1675,9 @@
 
 	to_qfl->qf_index = from_qfl->qf_index;	/* current index in the list */
 
+	/* Assign a new ID for the location list */
+	to_qfl->qf_id = ++last_qf_id;
+
 	/* When no valid entries are present in the list, qf_ptr points to
 	 * the first item in the list */
 	if (to_qfl->qf_nonevalid)
@@ -2808,6 +2814,7 @@
     qfl->qf_title = NULL;
     free_tv(qfl->qf_ctx);
     qfl->qf_ctx = NULL;
+    qfl->qf_id = 0;
 }
 
 /*
@@ -4628,6 +4635,7 @@
     QF_GETLIST_NR	= 0x4,
     QF_GETLIST_WINID	= 0x8,
     QF_GETLIST_CONTEXT	= 0x10,
+    QF_GETLIST_ID	= 0x20,
     QF_GETLIST_ALL	= 0xFF
 };
 
@@ -4688,17 +4696,17 @@
 	return qf_get_list_from_text(di, retdict);
 
     if (wp != NULL)
-    {
 	qi = GET_LOC_LIST(wp);
-	if (qi == NULL)
-	{
-	    /* If querying for the size of the location list, return 0 */
-	    if (((di = dict_find(what, (char_u *)"nr", -1)) != NULL)
-		    && (di->di_tv.v_type == VAR_STRING)
-		    && (STRCMP(di->di_tv.vval.v_string, "$") == 0))
-		return dict_add_nr_str(retdict, "nr", 0, NULL);
-	    return FAIL;
-	}
+
+    /* List is not present or is empty */
+    if (qi == NULL || qi->qf_listcount == 0)
+    {
+	/* If querying for the size of the list, return 0 */
+	if (((di = dict_find(what, (char_u *)"nr", -1)) != NULL)
+		&& (di->di_tv.v_type == VAR_STRING)
+		&& (STRCMP(di->di_tv.vval.v_string, "$") == 0))
+	    return dict_add_nr_str(retdict, "nr", 0, NULL);
+	return FAIL;
     }
 
     qf_idx = qi->qf_curlist;		/* default is the current list */
@@ -4714,41 +4722,52 @@
 		if (qf_idx < 0 || qf_idx >= qi->qf_listcount)
 		    return FAIL;
 	    }
-	    else if (qi->qf_listcount == 0)	    /* stack is empty */
-		return FAIL;
-	    flags |= QF_GETLIST_NR;
 	}
 	else if ((di->di_tv.v_type == VAR_STRING)
 		&& (STRCMP(di->di_tv.vval.v_string, "$") == 0))
-	{
 	    /* Get the last quickfix list number */
-	    if (qi->qf_listcount > 0)
-		qf_idx = qi->qf_listcount - 1;
-	    else
-		qf_idx = -1;	/* Quickfix stack is empty */
-	    flags |= QF_GETLIST_NR;
+	    qf_idx = qi->qf_listcount - 1;
+	else
+	    return FAIL;
+	flags |= QF_GETLIST_NR;
+    }
+
+    if ((di = dict_find(what, (char_u *)"id", -1)) != NULL)
+    {
+	/* Look for a list with the specified id */
+	if (di->di_tv.v_type == VAR_NUMBER)
+	{
+	    /* For zero, use the current list or the list specifed by 'nr' */
+	    if (di->di_tv.vval.v_number != 0)
+	    {
+		for (qf_idx = 0; qf_idx < qi->qf_listcount; qf_idx++)
+		{
+		    if (qi->qf_lists[qf_idx].qf_id == di->di_tv.vval.v_number)
+			break;
+		}
+		if (qf_idx == qi->qf_listcount)
+		    return FAIL;	    /* List not found */
+	    }
+	    flags |= QF_GETLIST_ID;
 	}
 	else
 	    return FAIL;
     }
 
-    if (qf_idx != -1)
-    {
-	if (dict_find(what, (char_u *)"all", -1) != NULL)
-	    flags |= QF_GETLIST_ALL;
+    if (dict_find(what, (char_u *)"all", -1) != NULL)
+	flags |= QF_GETLIST_ALL;
 
-	if (dict_find(what, (char_u *)"title", -1) != NULL)
-	    flags |= QF_GETLIST_TITLE;
+    if (dict_find(what, (char_u *)"title", -1) != NULL)
+	flags |= QF_GETLIST_TITLE;
 
-	if (dict_find(what, (char_u *)"winid", -1) != NULL)
-	    flags |= QF_GETLIST_WINID;
+    if (dict_find(what, (char_u *)"winid", -1) != NULL)
+	flags |= QF_GETLIST_WINID;
 
-	if (dict_find(what, (char_u *)"context", -1) != NULL)
-	    flags |= QF_GETLIST_CONTEXT;
+    if (dict_find(what, (char_u *)"context", -1) != NULL)
+	flags |= QF_GETLIST_CONTEXT;
 
-	if (dict_find(what, (char_u *)"items", -1) != NULL)
-	    flags |= QF_GETLIST_ITEMS;
-    }
+    if (dict_find(what, (char_u *)"items", -1) != NULL)
+	flags |= QF_GETLIST_ITEMS;
 
     if (flags & QF_GETLIST_TITLE)
     {
@@ -4798,6 +4817,10 @@
 	    status = dict_add_nr_str(retdict, "context", 0L, (char_u *)"");
     }
 
+    if ((status == OK) && (flags & QF_GETLIST_ID))
+	status = dict_add_nr_str(retdict, "id", qi->qf_lists[qf_idx].qf_id,
+									 NULL);
+
     return status;
 }
 
@@ -4983,6 +5006,21 @@
 	    return FAIL;
     }
 
+    if (!newlist && (di = dict_find(what, (char_u *)"id", -1)) != NULL)
+    {
+	/* Use the quickfix/location list with the specified id */
+	if (di->di_tv.v_type == VAR_NUMBER)
+	{
+	    for (qf_idx = 0; qf_idx < qi->qf_listcount; qf_idx++)
+		if (qi->qf_lists[qf_idx].qf_id == di->di_tv.vval.v_number)
+		    break;
+	    if (qf_idx == qi->qf_listcount)
+		return FAIL;	    /* List not found */
+	}
+	else
+	    return FAIL;
+    }
+
     if (newlist)
     {
 	qi->qf_curlist = qf_idx;