mercurial/parsers.c
changeset 19728 3daabd2da78b
parent 19727 3d07b4a2f743
child 20109 e57c532c3835
child 20110 40b7c6e4b993
equal deleted inserted replaced
19727:3d07b4a2f743 19728:3daabd2da78b
    75  * ('\n') characters.
    75  * ('\n') characters.
    76  */
    76  */
    77 static PyObject *parse_manifest(PyObject *self, PyObject *args)
    77 static PyObject *parse_manifest(PyObject *self, PyObject *args)
    78 {
    78 {
    79 	PyObject *mfdict, *fdict;
    79 	PyObject *mfdict, *fdict;
    80 	char *str, *cur, *start, *zero;
    80 	char *str, *start, *end;
    81 	int len;
    81 	int len;
    82 
    82 
    83 	if (!PyArg_ParseTuple(args, "O!O!s#:parse_manifest",
    83 	if (!PyArg_ParseTuple(args, "O!O!s#:parse_manifest",
    84 			      &PyDict_Type, &mfdict,
    84 			      &PyDict_Type, &mfdict,
    85 			      &PyDict_Type, &fdict,
    85 			      &PyDict_Type, &fdict,
    86 			      &str, &len))
    86 			      &str, &len))
    87 		goto quit;
    87 		goto quit;
    88 
    88 
    89 	for (start = cur = str, zero = NULL; cur < str + len; cur++) {
    89 	start = str;
       
    90 	end = str + len;
       
    91 	while (start < end) {
    90 		PyObject *file = NULL, *node = NULL;
    92 		PyObject *file = NULL, *node = NULL;
    91 		PyObject *flags = NULL;
    93 		PyObject *flags = NULL;
       
    94 		char *zero = NULL, *newline = NULL;
    92 		ptrdiff_t nlen;
    95 		ptrdiff_t nlen;
    93 
    96 
    94 		if (!*cur) {
    97 		zero = memchr(start, '\0', end - start);
    95 			zero = cur;
       
    96 			continue;
       
    97 		}
       
    98 		else if (*cur != '\n')
       
    99 			continue;
       
   100 
       
   101 		if (!zero) {
    98 		if (!zero) {
   102 			PyErr_SetString(PyExc_ValueError,
    99 			PyErr_SetString(PyExc_ValueError,
   103 					"manifest entry has no separator");
   100 					"manifest entry has no separator");
   104 			goto quit;
   101 			goto quit;
   105 		}
   102 		}
   106 
   103 
       
   104 		newline = memchr(zero + 1, '\n', end - (zero + 1));
       
   105 		if (!newline) {
       
   106 			PyErr_SetString(PyExc_ValueError,
       
   107 					"manifest contains trailing garbage");
       
   108 			goto quit;
       
   109 		}
       
   110 
   107 		file = PyBytes_FromStringAndSize(start, zero - start);
   111 		file = PyBytes_FromStringAndSize(start, zero - start);
   108 
   112 
   109 		if (!file)
   113 		if (!file)
   110 			goto bail;
   114 			goto bail;
   111 
   115 
   112 		nlen = cur - zero - 1;
   116 		nlen = newline - zero - 1;
   113 
   117 
   114 		node = unhexlify(zero + 1, nlen > 40 ? 40 : (int)nlen);
   118 		node = unhexlify(zero + 1, nlen > 40 ? 40 : (int)nlen);
   115 		if (!node)
   119 		if (!node)
   116 			goto bail;
   120 			goto bail;
   117 
   121 
   126 		}
   130 		}
   127 
   131 
   128 		if (PyDict_SetItem(mfdict, file, node) == -1)
   132 		if (PyDict_SetItem(mfdict, file, node) == -1)
   129 			goto bail;
   133 			goto bail;
   130 
   134 
   131 		start = cur + 1;
   135 		start = newline + 1;
   132 		zero = NULL;
       
   133 
   136 
   134 		Py_XDECREF(flags);
   137 		Py_XDECREF(flags);
   135 		Py_XDECREF(node);
   138 		Py_XDECREF(node);
   136 		Py_XDECREF(file);
   139 		Py_XDECREF(file);
   137 		continue;
   140 		continue;
   138 	bail:
   141 	bail:
   139 		Py_XDECREF(flags);
   142 		Py_XDECREF(flags);
   140 		Py_XDECREF(node);
   143 		Py_XDECREF(node);
   141 		Py_XDECREF(file);
   144 		Py_XDECREF(file);
   142 		goto quit;
       
   143 	}
       
   144 
       
   145 	if (len > 0 && *(cur - 1) != '\n') {
       
   146 		PyErr_SetString(PyExc_ValueError,
       
   147 				"manifest contains trailing garbage");
       
   148 		goto quit;
   145 		goto quit;
   149 	}
   146 	}
   150 
   147 
   151 	Py_INCREF(Py_None);
   148 	Py_INCREF(Py_None);
   152 	return Py_None;
   149 	return Py_None;