From 232c13caa35007bd61edeee6957fe5eb2a10dd89 Mon Sep 17 00:00:00 2001
From: Spoike <acceptthis@users.sourceforge.net>
Date: Wed, 31 Dec 2014 06:00:55 +0000
Subject: [PATCH] uri_get now transfers self to the callback too. id also has
 full float precision now. fix uri_post to not crash. fix weirdness with
 double-defined functions when the first was defined noref.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4812 fc73d0e0-1445-4013-8a0c-d673dee63da5
---
 engine/common/pr_bgcmd.c   | 14 +++++++++-----
 engine/http/httpclient.c   |  4 ++--
 engine/http/iweb.h         |  1 +
 engine/qclib/qcc_pr_comp.c | 27 ++++++++++++++++++++++++++-
 4 files changed, 38 insertions(+), 8 deletions(-)

diff --git a/engine/common/pr_bgcmd.c b/engine/common/pr_bgcmd.c
index b15c8c7c6..05b7f40c5 100644
--- a/engine/common/pr_bgcmd.c
+++ b/engine/common/pr_bgcmd.c
@@ -3648,20 +3648,23 @@ static void PR_uri_get_callback(struct dl_download *dl)
 {
 	world_t *w = dl->user_ctx;
 	pubprogfuncs_t *prinst = w->progs;
-	float id = dl->user_num;
+	float id = dl->user_float;
+	int selfnum = dl->user_num;
 	func_t func;
 
 	if (!prinst)
 		return;
 	
 	func = PR_FindFunction(prinst, "URI_Get_Callback", PR_ANY);
-
-	if (func)
+	if (!func)
+		Con_Printf("URI_Get_Callback missing\n");
+	else if (func)
 	{
 		int len;
 		char *buffer;
 		struct globalvars_s *pr_globals = PR_globals(prinst, PR_CURRENT);
 
+		*w->g.self = selfnum;
 		G_FLOAT(OFS_PARM0) = id;
 		G_FLOAT(OFS_PARM1) = (dl->replycode!=200)?dl->replycode:0;	//for compat with DP, we change any 200s to 0.
 		G_INT(OFS_PARM2) = 0;
@@ -3729,7 +3732,8 @@ void QCBUILTIN PF_uri_get  (pubprogfuncs_t *prinst, struct globalvars_s *pr_glob
 	if (dl)
 	{
 		dl->user_ctx = w;
-		dl->user_num = id;
+		dl->user_float = id;
+		dl->user_num = *w->g.self;
 		G_FLOAT(OFS_RETURN) = 1;
 	}
 	else
@@ -5374,7 +5378,7 @@ lh_extension_t QSG_Extensions[] = {
 	{"DP_QC_UNLIMITEDTEMPSTRINGS"},
 	{"DP_QC_URI_ESCAPE",				2,	NULL, {"uri_escape", "uri_unescape"}},
 	{"DP_QC_URI_GET",					1,	NULL, {"uri_get"}},
-//test	{"DP_QC_URI_POST",					1,	NULL, {"uri_get"}},
+	{"DP_QC_URI_POST",					1,	NULL, {"uri_get"}},
 	{"DP_QC_VECTOANGLES_WITH_ROLL"},
 	{"DP_QC_VECTORVECTORS",				1,	NULL, {"vectorvectors"}},
 	{"DP_QC_WHICHPACK",					1,	NULL, {"whichpack"}},
diff --git a/engine/http/httpclient.c b/engine/http/httpclient.c
index c0da149b5..578fa6d8a 100644
--- a/engine/http/httpclient.c
+++ b/engine/http/httpclient.c
@@ -277,7 +277,7 @@ It doesn't use persistant connections.
 */
 
 struct http_dl_ctx_s {
-	struct dl_download *dlctx;
+//	struct dl_download *dlctx;
 
 #if 1
 	vfsfile_t *sock;
@@ -801,7 +801,7 @@ void HTTPDL_Establish(struct dl_download *dl)
 #endif
 	if (dl->postdata)
 	{
-		ExpandBuffer(con, 1024 + strlen(uri) + strlen(server) + strlen(con->dlctx->postmimetype) + dl->postlen);
+		ExpandBuffer(con, 1024 + strlen(uri) + strlen(server) + strlen(dl->postmimetype) + dl->postlen);
 		Q_snprintfz(con->buffer, con->bufferlen,
 			"POST %s HTTP/1.1\r\n"
 			"Host: %s\r\n"
diff --git a/engine/http/iweb.h b/engine/http/iweb.h
index 3a46d6917..bb26364ff 100644
--- a/engine/http/iweb.h
+++ b/engine/http/iweb.h
@@ -101,6 +101,7 @@ struct dl_download
 {
 	/*not used by anything in the download itself, useful for context*/
 	unsigned int user_num;
+	float user_float;
 	void *user_ctx;
 
 	qdownload_t qdownload;
diff --git a/engine/qclib/qcc_pr_comp.c b/engine/qclib/qcc_pr_comp.c
index 802ee9b6f..e57ffa6e2 100644
--- a/engine/qclib/qcc_pr_comp.c
+++ b/engine/qclib/qcc_pr_comp.c
@@ -10771,7 +10771,32 @@ void QCC_PR_ParseInitializerType(int arraysize, QCC_def_t *def, QCC_type_t *type
 					f = NULL;
 			}
 			else
+			{
+				if (def->initialized == 1)
+				{
+					//normally this is an error, but to aid supporting new stuff with old, we convert it into a warning if a vanilla(ish) qc function replaces extension builtins.
+					//the qc function is the one that is used, but there is a warning so you know how to gain efficiency.
+					int bi = -1;
+					if (def->type->type == ev_function && !arraysize)
+					{
+						if (!strcmp(def->name, "anglemod"))
+							bi = G_INT(def->ofs);
+					}
+					if (bi <= 0 || bi >= numfunctions)
+						bi = 0;
+					else
+						bi = functions[bi].first_statement;
+					if (bi < 0)
+					{
+						QCC_PR_ParseWarning(WARN_NOTSTANDARDBEHAVIOUR, "%s already declared as builtin", def->name);
+						QCC_PR_ParsePrintDef(WARN_NOTSTANDARDBEHAVIOUR, def);
+						def->initialized = 3;
+					}
+					else
+						QCC_PR_ParseErrorPrintDef (ERR_REDECLARATION, def, "redeclaration of function body");
+				}
 				f = QCC_PR_ParseImmediateStatements (type);
+			}
 			if (!tmp)
 			{
 				pr_scope = parentfunc;
@@ -10935,7 +10960,7 @@ void QCC_PR_ParseInitializerType(int arraysize, QCC_def_t *def, QCC_type_t *type
 void QCC_PR_ParseInitializerDef(QCC_def_t *def)
 {
 	QCC_PR_ParseInitializerType(def->arraysize, def, def->type, def->ofs);
-	if (!def->initialized)
+	if (!def->initialized || def->initialized == 3)
 		def->initialized = 1;
 }