libnetconf DOC documentation significantly improved

--- src/libnetconf.h
+++ src/libnetconf.h
@@ -78,11 +78,11 @@
  * @page howtoinit Init and Thread-safety Information
  *
  * Before working with the library, it must be initialized using nc_client_init()
- * or nc_server_init(). Based on how the library was compiled, also libssh and/or
- * libssh/libcrypto are initialized (for multi-threaded use) too. It is advised
- * to compile libnetconf2, for instance, with TLS support even if you do not want
- * to use lnc2 TLS functions, but only use libssl/libcrypto functions in your
- * application. You can then use libnetconf2 cleanup function and do not
+ * or nc_server_init(). Based on how the library was compiled, also _libssh_ and/or
+ * _libssh_/_libcrypto_ are initialized (for multi-threaded use) too. It is advised
+ * to compile _libnetconf2_, for instance, with TLS support even if you do not want
+ * to use _lnc2_ TLS functions, but only use _libssl/libcrypto_ functions in your
+ * application. You can then use _libnetconf2_ cleanup function and do not
  * trouble yourself with the cleanup.
  *
  * To prevent any reachable memory at the end of your application, there
@@ -91,13 +91,13 @@
  * the other threads have ended. In every other thread you should call
  * nc_thread_destroy() just before it exits.
  *
- * If libnetconf2 is used in accordance with this information, there should
+ * If _libnetconf2_ is used in accordance with this information, there should
  * not be memory leaks of any kind at program exit. For thread-safety details
- * of libssh, libssl, and libcrypto please refer to the corresponding project
- * documentation. libnetconf2 thread-safety information is below.
- *
- * Client is NOT thread-safe and there is no access control in the client
- * functions at all. Server is MOSTLY thread-safe meaning you can set all the
+ * of _libssh_, _libssl_, and _libcrypto_, please refer to the corresponding project
+ * documentation. _libnetconf2_ thread-safety information is below.
+ *
+ * Client is __NOT__ thread-safe and there is no access control in the client
+ * functions at all. Server is __MOSTLY__ thread-safe meaning you can set all the
  * options simultaneously while listening for or accepting new sessions or
  * polling the existing ones. It should even be safe to poll one session in
  * several threads, but it is definitely discouraged. Generally, servers can
@@ -125,6 +125,13 @@
 /**
  * @page howtoclient Client sessions
  *
+ * To connect to a NETCONF server, a NETCONF session must be established,
+ * which requires a working transport session. It is possible to create
+ * NETCONF sessions with SSH (using _libssh_) or TLS (using _libssl/libcrypto_)
+ * as the underlying transport protocol. It is also possible to establish
+ * the transport protocol outside _libnetconf2_ and then provide these file
+ * descriptors (FD) for full NETCONF session creation.
+ *
  * There are a lot of options for both an SSH and a TLS client. All of them
  * have setters and getters so that there is no need to duplicate them in
  * a client.
@@ -132,16 +139,24 @@
  * SSH
  * ===
  *
- * It is mostly required to set any SSH options and then simply connect to
- * a NETCONF server. Optionally, some authetication callbacks can be set,
+ * Connecting to a server using SSH does not strictly require to set any
+ * options, there are sensible default values for all the basic ones.
+ * Except all the SSH options, optionally some authetication callbacks can be set,
  * which are particulary useful in automated clients (passwords cannot be
  * asked a user) or simply if any additional information is retrieved some
  * other way than from standard terminal input.
  *
- * Afterwards, there are 2 functions to use for a new server connection
- * and an additional one for creating a new SSH channel on an existing
- * NETCONF session. The libssh variant enables to customize the SSH session
- * in every way the libssh allows, although that should not normally be needed.
+ * Having the default options or changing any unsuitable ones, there are 2 functions
+ * to use for a new server connection. nc_connect_ssh() is the standard function
+ * that creates sessions using the set options. If there are some options, which
+ * cannot be changed with the provided API, there is nc_connect_libssh() available.
+ * It requires a _libssh_ session, in which all the SSH options can be modified
+ * and even the connection established. This allows for full customization and
+ * should fit any specific situation.
+ *
+ * New NETCONF sessions can also be created on existing authenticated SSH sessions.
+ * There is a new SSH channel needed, on which the NETCONF session is then created.
+ * Use nc_connect_ssh_channel() for this purpose.
  *
  * Functions List
  * --------------
@@ -169,11 +184,15 @@
  * TLS
  * ===
  *
- * With TLS authentication, is is mandatory to set the client certificate
- * with a private key and additional trusted certificates and revocation lists.
- *
- * Then there are again 2 functions for connecting, the libssl variant enables
- * to customize the TLS session in every way the libssl allows.
+ * To connect to a server using TLS, there must be some client identification
+ * options set. Client must specify its certificate with a private key using
+ * nc_client_tls_set_cert_key_paths(). Also, the Certificate Authority of
+ * a server certificate must be considered trusted. Paths to all the trusted
+ * CA certificates can be set by nc_client_tls_set_trusted_ca_paths().
+ *
+ * Then there are again 2 functions for connecting, nc_connect_tls() being
+ * the standard way of connecting. nc_connect_libssl() again enables
+ * to customize the TLS session in every way _libssl_ allows.
  *
  * Functions List
  * --------------
@@ -195,8 +214,8 @@
  * ==
  *
  * If you authenticated the connection using some tunneling software, you
- * can pass its file descriptors to libnetconf2, which will continue to
- * establish a full NETCONF session.
+ * can pass its file descriptors to _libnetconf2_ using nc_connect_inout(),
+ * which will continue to establish a full NETCONF session.
  *
  * Funtions List
  * -------------
@@ -211,8 +230,9 @@
  *
  * Call Home needs the same options set as standard SSH or TLS and the functions
  * reflect it exactly. However, to accept a connection, the client must first
- * specify addresses and ports, which to listen on. Then connections can be
- * accepted.
+ * specify addresses and ports, which to listen on by nc_client_ssh_ch_add_bind_listen()
+ * and nc_client_tls_ch_add_bind_listen(). Then connections can be
+ * accepted using nc_accept_callhome().
  *
  * Functions List
  * --------------
@@ -250,15 +270,7 @@
  * =======
  *
  * These options and the schema searchpath are stored in dynamically
- * allocated memory. To free it, destroy the client, it cleans up all
- * the options
- *
- * Functions List
- * --------------
- *
- * Available in __nc_client.h__.
- *
- * - nc_client_destroy()
+ * allocated memory. They are freed as a part of [destroying the client](@ref howtoinit).
  */

 /**
@@ -270,14 +282,21 @@
  * Server takes an argument for its [initialization function](@ref howtoinit).
  * In it, you set the server context, which determines what modules it
  * supports and what capabilities to advertise. Few capabilities that
- * cannot be learnt from the context are set with separate functions.
- * So are several general options.
+ * cannot be learnt from the context are set with separate functions
+ * nc_server_set_capab_withdefaults() and nc_server_set_capab_interleave().
+ * Timeout for receiving the _hello_ message on a new session can be set
+ * by nc_server_set_hello_timeout() and the timeout for disconnecting
+ * an inactive session by nc_server_set_idle_timeout().
  *
  * Context does not only determine server modules, but its overall
  * functionality as well. For every RPC the server should support,
  * an nc_rpc_clb callback should be set on that node in the context.
  * Server then calls these as appropriate [during poll](@ref howtoservercomm).
  *
+ * Just like in the [client](@ref howtoclient), you can let _libnetconf2_
+ * establish SSH or TLS transport or do it yourself and only provide the file
+ * descriptors of the connection.
+ *
  * Server options can be only set, there are no getters.
  *
  * Functions List
@@ -294,8 +313,10 @@
  * SSH
  * ===
  *
- * To be able to accept SSH connections, an endpoint must be added
- * and its options set.
+ * To be able to accept SSH connections, individual endpoints must be added
+ * with nc_server_ssh_add_endpt_listen() and their options set. The only
+ * mandatory SSH option before sessions can be established on an endpoint
+ * is the host key, set it using nc_server_ssh_endpt_set_hostkey().
  *
  * Functions List
  * --------------
@@ -319,9 +340,28 @@
  * TLS
  * ===
  *
- * TLS requires at least one endpoint too, but its options differ
- * significantly from the SSH ones, especially in the cert-to-name
+ * TLS works with endpoints too, but its options differ
+ * significantly from the SSH ones, especially in the _cert-to-name_
  * options that TLS uses to derive usernames from client certificates.
+ * So, after starting listening on an endpoint with nc_server_tls_add_endpt_listen(),
+ * you need to set the server certificate (nc_server_tls_endpt_set_cert()
+ * or nc_server_tls_endpt_set_cert_path()) and private key (nc_server_tls_endpt_set_key()
+ * or nc_server_tls_endpt_set_key_path()).
+ *
+ * To accept client certificates, they must first be considered trusted,
+ * which you have three ways of achieving. You can add each of their Certificate Authority
+ * certificates to the trusted ones or mark a specific client certificate
+ * as trusted using nc_server_tls_endpt_add_trusted_cert(). Lastly, you can
+ * set paths with all the trusted CA certificates with nc_server_tls_endpt_set_trusted_ca_paths().
+ *
+ * Then, from each trusted client certificate a username must be derived
+ * for the NETCONF session. This is accomplished by finding a matching
+ * _cert-to-name_ entry. They are added using nc_server_tls_endpt_add_ctn().
+ *
+ * If you need to remove trusted certificates or Certificate Revocation
+ * Lists, you must first clear them all with nc_server_tls_endpt_clear_certs()
+ * and nc_server_tls_endpt_clear_crls(), respectively. Then add all
+ * the certificates again.
  *
  * Functions List
  * --------------
@@ -350,7 +390,8 @@
  * ==
  *
  * If you used a tunneling software, which does its own authentication,
- * you can accept a NETCONF session on its file descriptors.
+ * you can accept a NETCONF session on its file descriptors with
+ * nc_accept_inout().
  *
  * Functions List
  * --------------
@@ -364,7 +405,10 @@
  * =========
  *
  * Call Home does not work with endpoints like standard sessions.
- * The options must be reset manually after another Call Home session
+ * Connecting is similar to the [client](@ref howtoclient), just call
+ * nc_connect_callhome_ssh() or nc_connect_callhome_tls(). Any options
+ * must be reset manually by nc_server_ssh_ch_clear_opts()
+ * or nc_server_tls_ch_clear_crls() after another Call Home session
  * (with different options than the previous one) is to be established.
  * Also, monitoring of these sessions is up to the application.
  *
@@ -403,9 +447,9 @@
  * Connecting And Cleanup
  * ======================
  *
- * When accepting connections, all the endpoints are examined
+ * When accepting connections with nc_accept(), all the endpoints are examined
  * and the first with a pending connection is used. To remove all
- * the endpoints and free any used dynamic memory, destroy the server.
+ * the endpoints and free any used dynamic memory, [destroy](@ref howtoinit) the server.
  *
  * Functions List
  * --------------
@@ -413,19 +457,17 @@
  * Available in __nc_server.h__.
  *
  * - nc_accept()
- *
- * - nc_server_destroy()
  */

 /**
  * @page howtoclientcomm Client communication
  *
- * To send RPCs on a session, you simply create an RPC, send it,
- * and then wait for a reply. If you are subscribed, there are 2 ways
+ * To send RPCs on a session, you simply create an RPC, send it using nc_send_rpc(),
+ * and then wait for a reply using nc_recv_reply(). If you are subscribed, there are 2 ways
  * of receiving notifications. Either you wait for them the same way
- * as for standard replies or you create a dispatcher that asynchronously
- * (in a separate thread) reads notifications and passes them to your
- * callback.
+ * as for standard replies with nc_recv_notif() or you create a dispatcher
+ * with nc_recv_notif_dispatch() that asynchronously (in a separate thread)
+ * reads notifications and passes them to your callback.
  *
  * Functions List
  * --------------
@@ -459,15 +501,19 @@
  * @page howtoservercomm Server communication
  *
  * Once at least one session is established, an nc_pollsession structure
- * should be created, filled with the session and polled. Based on
- * the return value from the poll further actions can be taken. More
- * sessions can be polled at the same time. Any requests received on
+ * should be created with nc_ps_new(), filled with the session using
+ * nc_ps_add_session() and finally polled with nc_ps_poll(). Based on
+ * the return value from the poll, further actions can be taken. More
+ * sessions can be polled at the same time and any requests received on
  * the sessions are [handled internally](@ref howtoserver).
  *
- * Functions List
- * --------------
- *
- * Available in __nc_client.h__.
+ * If an SSH NETCONF session asks for a new channel, you can accept
+ * this request with nc_ps_accept_ssh_channel().
+ *
+ * Functions List
+ * --------------
+ *
+ * Available in __nc_server.h__.
  *
  * - nc_ps_new()
  * - nc_ps_add_session()


RC_SYS should now set XEN0 correctly

RC_SYS should now set XEN0 correctly

--- src/librc-misc.c
+++ src/librc-misc.c
@@ -677,13 +677,15 @@
 			if (file_regex ("/proc/xen/capabilities", "control_d"))
 				snprintf (sys, sizeof (sys), "XENU");
 		}
-		if (! sys)
+		if (! sys[0])
 			snprintf (sys, sizeof (sys), "XEN0");
-	} else if (file_regex ("/proc/cpuinfo", "UML"))
+	} else if (file_regex ("/proc/cpuinfo", "UML")) {
 		snprintf (sys, sizeof (sys), "UML");
-	else if (file_regex ("/proc/self/status",
-						 "(s_context|VxID|envID):[[:space:]]*[1-9]"))
-													snprintf (sys, sizeof (sys), "VPS");
+	} else if (file_regex ("/proc/self/status",
+						   "(s_context|VxID|envID):[[:space:]]*[1-9]"))
+	{
+		snprintf (sys, sizeof (sys), "VPS");
+	}
 #endif

 	/* Only add a NET_FS list if not defined */


Debug: Fix an oops from converting D_JUMP to msgbuf incorrectly.

--- src/lily_debug.c
+++ src/lily_debug.c
@@ -467,7 +467,7 @@
             }
             else if (data_code == D_JUMP) {
                 lily_msgbuf_add_fmt(msgbuf, "^I|     -> | [%d]\n",
-                        (int)code[i+j]);
+                        indent, (int)code[i+j]);
                 write_msgbuf(debug);
             }
             else if (data_code == D_COUNT)


svg_filter: implement BackgroundImage and BackgroundAlpha.

--- src/lsmsvgview.c
+++ src/lsmsvgview.c
@@ -1690,21 +1690,44 @@

 		return surface;
 	} else if (g_strcmp0 (input, "BackgroundImage") == 0) {
-		/* TODO */
 		LsmSvgFilterSurface *surface;
-
-		lsm_warning_render ("LsmSvgView::get_filter_surface] BackgroundImage is not yet implemented");
+		cairo_surface_t *background_surface;
+		cairo_matrix_t matrix;
+		cairo_matrix_t pattern_matrix;
+		cairo_t *cairo;

 		surface = lsm_svg_filter_surface_new_similar ("BackgroundImage", source_surface, NULL);
 		view->filter_surfaces = g_slist_prepend (view->filter_surfaces, surface);
+
+		background_surface = cairo_get_target (view->pattern_data->old_cairo);
+		cairo_get_matrix (view->pattern_data->old_cairo, &matrix);
+		cairo_pattern_get_matrix (view->pattern_data->pattern, &pattern_matrix);
+
+		cairo_matrix_invert (&matrix);
+		cairo_matrix_multiply (&matrix, &matrix, &pattern_matrix);
+
+		lsm_debug_render ("[LsmSvgView::_get_filter_surface] Background image matrix %g, %g, %g, %g, %g, %g\n",
+				  matrix.xx, matrix.xy, matrix.yx, matrix.yy,
+				  matrix.x0, matrix.y0);
+
+		cairo = cairo_create (lsm_svg_filter_surface_get_cairo_surface (surface));
+		cairo_set_matrix (cairo, &matrix);
+		cairo_set_source_surface (cairo, background_surface, 0, 0);
+		cairo_paint (cairo);
+		cairo_destroy (cairo);
+
+		return surface;
 	} else if (g_strcmp0 (input, "BackgroundAlpha") == 0) {
-		/* TODO */
 		LsmSvgFilterSurface *surface;
-
-		lsm_warning_render ("LsmSvgView::get_filter_surface] BackgroundAlpha is not yet implemented");
-
-		surface = lsm_svg_filter_surface_new_similar ("BackgroundAlpha", source_surface, NULL);
+		LsmSvgFilterSurface *background_surface;
+
+		background_surface = _get_filter_surface (view, "BackgroundImage");
+
+		surface = lsm_svg_filter_surface_new_similar ("BackgroundAlpha", background_surface, NULL);
+		lsm_svg_filter_surface_alpha (background_surface, surface);
 		view->filter_surfaces = g_slist_prepend (view->filter_surfaces, surface);
+
+		return surface;
 	}

 	return NULL;


- Fixed a possible crash when the memory manager is disabled and a non-respawning object is killed.

git-svn-id: c1e39603916b71782cde5facdf0b79eff05c1414@11857 54d463be-8e91-2dee-dedb-b68131a5f0ec

--- src/map/battle.c
+++ src/map/battle.c
@@ -155,6 +155,7 @@
 	if (target && dat && map_id2bl(id) == dat->src && target->prev != NULL && !status_isdead(target) &&
 		target->m == dat->src->m && check_distance_bl(dat->src, target, dat->distance)) //Check to see if you haven't teleported. [Skotlex]
 	{
+		map_freeblock_lock();
 		status_fix_damage(dat->src, target, dat->damage, dat->delay);
 		if ((dat->dmg_lv == ATK_DEF || dat->damage > 0) && dat->attack_type)
 		{
@@ -162,7 +163,7 @@
 				skill_additional_effect(dat->src,target,dat->skill_id,dat->skill_lv,dat->attack_type,tick);
 			skill_counter_additional_effect(dat->src,target,dat->skill_id,dat->skill_lv,dat->attack_type,tick);
 		}
-
+		map_freeblock_unlock();
 	}
 	ers_free(delay_damage_ers, dat);
 	return 0;
@@ -175,6 +176,7 @@
 	nullpo_retr(0, target);

 	if (!battle_config.delay_battle_damage) {
+		map_freeblock_lock();
 		status_fix_damage(src, target, damage, ddelay);
 		if ((damage > 0 || dmg_lv == ATK_DEF) && attack_type)
 		{
@@ -182,6 +184,7 @@
 				skill_additional_effect(src, target, skill_id, skill_lv, attack_type, gettick());
 			skill_counter_additional_effect(src, target, skill_id, skill_lv, attack_type, gettick());
 		}
+		map_freeblock_unlock();
 		return 0;
 	}
 	dat = ers_alloc(delay_damage_ers, struct delay_damage);


Fixing the last buildbot warning; should brian be happy, we'll open champagne

git-svn-id: c1e39603916b71782cde5facdf0b79eff05c1414@15068 54d463be-8e91-2dee-dedb-b68131a5f0ec

--- src/map/script.c
+++ src/map/script.c
@@ -12971,7 +12971,7 @@

     // Need not be parsed, just solve stuff like %%.
     if(argc==0){
-        sprintf(buf, format);
+		memcpy(buf,format,len+1);
         script_pushstrcopy(st, buf);
         aFree(buf);
         return 0;


#91945# fixed danger get

#91945# fixed danger get

--- cppu/inc/typelib/typedescription.h
+++ cppu/inc/typelib/typedescription.h
@@ -2,9 +2,9 @@
  *
  *  $RCSfile: typedescription.h,v $
  *
- *  $Revision: 1.9 $
- *
- *  last change: $Author: dbo $ $Date: 2001-08-21 09:17:07 $
+ *  $Revision: 1.10 $
+ *
+ *  last change: $Author: dbo $ $Date: 2001-09-06 14:53:29 $
  *
  *  The Contents of this file are made available subject to the terms of
  *  either of the following licenses
@@ -705,7 +705,7 @@
     { \
         typelib_typedescriptionreference_getDescription( __ppMacroTypeDescr, __pMacroTypeRef ); \
     } \
-    else if (! __pMacroTypeRef->pType->pWeakRef) \
+    else if (!__pMacroTypeRef->pType || !__pMacroTypeRef->pType->pWeakRef) \
     { \
         typelib_typedescriptionreference_getDescription( __ppMacroTypeDescr, __pMacroTypeRef ); \
         if (*__ppMacroTypeDescr) \


Force no event when calling the grammar parse() method [ci skip]

--- src/marpaESLIF.c
+++ src/marpaESLIF.c
@@ -539,8 +539,8 @@
     /* Fake a recognizer. EOF flag will be set automatically in fake mode */
     marpaESLIFRecognizerp = _marpaESLIFRecognizer_newp(&marpaESLIFGrammar,
                                                        NULL /* marpaESLIFRecognizerOptionp */,
-                                                       0 /* discardb - no used anway because we are in fake mode */,
-                                                       0 /* noEventb - no used anway because we are in fake mode */,
+                                                       0 /* discardb - not used anyway because we are in fake mode */,
+                                                       0 /* noEventb - not used anyway because we are in fake mode */,
                                                        NULL /* exceptionStackp */,
                                                        0 /* silentb */,
                                                        NULL /* marpaESLIFRecognizerParentp */,
@@ -789,8 +789,8 @@
       /* Fake a recognizer. EOF flag will be set automatically in fake mode */
       marpaESLIFRecognizerp = _marpaESLIFRecognizer_newp(&marpaESLIFGrammar,
                                                          NULL /* marpaESLIFRecognizerOptionp */,
-                                                         0 /* discardb - no used anway because we are in fake mode */,
-                                                         0 /* noEventb - no used anway because we are in fake mode */,
+                                                         0 /* discardb - not used anyway because we are in fake mode */,
+                                                         0 /* noEventb - not used anyway because we are in fake mode */,
                                                          NULL /* exceptionStackp */,
                                                          0 /* silentb */,
                                                          NULL /* marpaESLIFRecognizerParentp */,
@@ -958,8 +958,8 @@
     /* Fake a recognizer. EOF flag will be set automatically in fake mode */
     marpaESLIFRecognizerTestp = _marpaESLIFRecognizer_newp(&marpaESLIFGrammar,
                                                            NULL /* marpaESLIFRecognizerOptionp */,
-                                                           0 /* discardb - no used anway because we are in fake mode */,
-                                                           0 /* noEventb - no used anway because we are in fake mode */,
+                                                           0 /* discardb - not used anyway because we are in fake mode */,
+                                                           0 /* noEventb - not used anyway because we are in fake mode */,
                                                            NULL /* exceptionStackp */,
                                                            0 /* silentb */,
                                                            NULL /* marpaESLIFRecognizerParentp */,
@@ -5490,11 +5490,11 @@
   if (! _marpaESLIFGrammar_parseb(&marpaESLIFGrammar,
                                   marpaESLIFRecognizerOptionp,
                                   marpaESLIFValueOptionp,
-                                  0 /* discardb */,
-                                  0 /* noEventb */,
-                                  NULL /* exceptionStackp */,
-                                  0 /* silentb */,
-                                  NULL /* marpaESLIFRecognizerParentp */,
+                                  0, /* discardb */
+                                  1, /* noEventb - this will make the recognizer use marpaWrapperGrammarStartNoEventp */
+                                  NULL, /* exceptionStackp */
+                                  0, /* silentb */
+                                  NULL, /* marpaESLIFRecognizerParentp */
                                   exhaustedbp,
                                   marpaESLIFValueResultp)) {
     goto err;
@@ -8615,11 +8615,11 @@
   marpaESLIFGrammar.marpaESLIFp = marpaESLIFp;
   /* Fake a recognizer. EOF flag will be set automatically in fake mode */
   marpaESLIFRecognizerp = _marpaESLIFRecognizer_newp(&marpaESLIFGrammar,
-                                                     NULL /* marpaESLIFRecognizerOptionp */,
-                                                     0 /* discardb - no effect anyway because we are in fake mode */,
-                                                     1 /* noEventb - no effect anyway because we are in fake mode -; */,
-                                                     NULL /* exceptionStackp */,
-                                                     0 /* silentb */,
+                                                     NULL, /* marpaESLIFRecognizerOptionp */
+                                                     0, /* discardb - no effect anyway because we are in fake mode */
+                                                     1, /* noEventb - no effect anyway because we are in fake mode */
+                                                     NULL, /* exceptionStackp */
+                                                     0, /* silentb */
                                                      marpaESLIFRecognizerParentp,
                                                      1 /* fakeb */);
   if (marpaESLIFRecognizerp == NULL) {


Fix bug with setting atLineEnd at end of document.

--- lexlib/StyleContext.h
+++ lexlib/StyleContext.h
@@ -76,7 +76,7 @@
 		// End of line?
 		// Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win)
 		// or on LF alone (Unix). Avoid triggering two times on Dos/Win.
-		if (lineStartNext < styler.Length())
+		if (currentLine < lineDocEnd)
 			atLineEnd = static_cast<int>(pos) >= (lineStartNext-1);
 		else // Last line
 			atLineEnd = static_cast<int>(pos) >= lineStartNext;
@@ -85,6 +85,7 @@
 public:
 	unsigned int currentPos;
 	int currentLine;
+	int lineDocEnd;
 	int lineStartNext;
 	bool atLineStart;
 	bool atLineEnd;
@@ -112,6 +113,7 @@
 		lengthDocument = static_cast<unsigned int>(styler.Length());
 		if (endPos == lengthDocument)
 			endPos++;
+		lineDocEnd = styler.GetLine(lengthDocument);
 		atLineStart = static_cast<unsigned int>(styler.LineStart(currentLine)) == startPos;
 		unsigned int pos = currentPos;
 		ch = static_cast<unsigned char>(styler.SafeGetCharAt(pos, 0));


src/marpaESLIF.c: MARPAESLIF_SYMBOL_CREATESHOW() for neighbour meta [ci skip]


src/marpaESLIF.c: Changed a MARPAESLIF_UNLIKELY() to MARPAESLIF_LIKELY() [ci skip]


mds: set issue_stamp on cap reconnect

mds: set issue_stamp on cap reconnect

--- src/mds/CInode.h
+++ src/mds/CInode.h
@@ -588,6 +588,7 @@
       cap->set_wanted(icr.wanted);
       cap->issue(icr.issued);
     }
+    cap->set_last_issue_stamp(g_clock.recent_now());
     inode.size = MAX(inode.size, icr.size);
     inode.mtime = MAX(inode.mtime, utime_t(icr.mtime));
     inode.atime = MAX(inode.atime, utime_t(icr.atime));


BUG: Removing old source file.

BUG: Removing old source file.

SVN-Revision: 84

--- src/metaMatrix.h
+++ src/metaMatrix.h
@@ -1,221 +0,0 @@
-/*=========================================================================
-
-  Program:   MetaIO
-  Module:    $RCSfile$
-  Language:  C++
-  Date:      $Date$
-  Version:   $Revision$
-
-  Copyright (c) Insight Software Consortium. All rights reserved.
-  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
-
-     This software is distributed WITHOUT ANY WARRANTY; without even
-     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-     PURPOSE.  See the above copyright notices for more information.
-
-=========================================================================*/
-#include "metaTypes.h"
-
-#ifndef ITKMetaIO_METAVECTOR_H
-#define ITKMetaIO_METAVECTOR_H
-
-#include "metaUtils.h"
-#include "metaForm.h"
-
-/*!    MetaMatrix (.h and .cpp)
- *
- * Description:
- *    Reads and Writes MetaMatrix Files.
- *    MetaMatrix Files can be in one of two possible formats:
- *       a combined header/data format, typically designated .mva files
- *       or as separate header and data files, typically designated
- *       .mvh and .mvd files
- *
- * Features:
- *    Header information is in ascii format - for easy creation, editing,
- *      and review.
- *    Has required and optional header data (provides rapid formation
- *      or extensive documentation).
- *    Handles byte ordering (MSB/LSB)
- *    REQUIRED: NDims, ByteOrderMSB, ElementDataType, DataFileName
- *
- * \author Stephen R. Aylward
- *
- * \date August 29, 1999
- *
- * Depends on:
- *    MetaUtils.h
- *    MetaForm.h
- */
-
-#if (METAIO_USE_NAMESPACE)
-namespace METAIO_NAMESPACE {
-#endif
-
-class METAIO_EXPORT MetaMatrix : public MetaForm
-  {
-  /////
-  //
-  // PUBLIC
-  //
-  ////
-  public:
-
-    ////
-    //
-    // Constructors & Destructor
-    //
-    ////
-    MetaMatrix(void);
-
-    MetaMatrix(const char *_headerName);
-
-    MetaMatrix(MetaMatrix *_vector,
-              bool _allocateElementData=false,
-              bool _autoFreeElementData=false);
-
-    MetaMatrix(int _ncolumns, int _nrows,
-              MET_ValueEnumType _elementType,
-              int _elementNumberOfChannels=1,
-              void *_elementData=NULL,
-              bool _allocateElementData=false,
-              bool _autoFreeElementData=false);
-
-    ~MetaMatrix(void);
-
-    void  PrintInfo(void) const;
-
-    void  CopyInfo(const MetaForm * _form);
-
-    void  Clear(void);
-
-    bool  InitializeEssential(int _nDims,
-                              MET_ValueEnumType _elementType,
-                              int _elementNumberOfChannels=1,
-                              void *_elementData=NULL,
-                              bool _allocateElementData=false,
-                              bool _autoFreeElementData=true);
-
-    bool  AllocateElementData(bool _autoFreeElementData=true);
-
-    int   NumberOfRows(void) const;
-    void  NumberOfRows(int _length);
-
-    int   NumberOfColumns(void) const;
-    void  NumberOfColumns(int _length);
-
-    int   NDims(void) const;
-
-    MET_ValueEnumType ElementType(void) const;
-    void              ElementType(MET_ValueEnumType _elementType);
-
-    int   ElementNumberOfChannels(void) const;
-    void  ElementNumberOfChannels(int _elementNumberOfChannels);
-
-    //
-    //
-    //
-    void  ElementByteOrderSwap(void);
-    bool  ElementByteOrderFix(void);
-
-    //
-    //    ConverTo(...)
-    //       Converts to a new data type
-    bool  ConvertElementDataTo(MET_ValueEnumType _toElementType,
-                               double _fromMin=0,
-                               double _fromMax=0,
-                               double _toMin=0,
-                               double _toMax=0);
-
-    bool  ImportBufferToElementData(const void *_fromBuffer,
-                                    MET_ValueEnumType _fromBufferType,
-                                    double _fromMin=0,
-                                    double _fromMax=0,
-                                    double _toMin=0,
-                                    double _toMax=0);
-
-    //
-    //
-    //
-    bool         AutoFreeElementData(void) const;
-    void         AutoFreeElementData(bool _freeData);
-
-    const char * ElementDataFileName(void) const;
-    void         ElementDataFileName(const char * _dataFileName);
-
-    void *       ElementData(void);
-    double       ElementData(int _i, int _j) const;
-    void         ElementData(void * _data, bool _autoFreeElementData=false);
-    bool         ElementData(int _i, int _j, double _v);
-
-    //
-    //
-    //
-    virtual bool CanRead(const char *_headerName=NULL) const;
-
-    virtual bool Read(const char *_headerName=NULL,
-                      bool _readElements=true,
-                      void * _elementDataBuffer=NULL,
-                      bool _autoFreeElementData=false);
-
-    virtual bool CanReadStream(METAIO_STREAM::ifstream * _stream) const;
-
-    virtual bool ReadStream(METAIO_STREAM::ifstream * _stream,
-                            bool _readElements=true,
-                            void * _elementDataBuffer=NULL,
-                            bool _autoFreeElementData=false);
-
-    virtual bool Write(const char *_headName=NULL,
-                       const char *_dataName=NULL,
-                       bool _writeElements=true,
-                       const void * _constElementData=NULL);
-
-    virtual bool WriteStream(METAIO_STREAM::ofstream * _stream,
-                             bool _writeElements=true,
-                             const void * _constElementData=NULL);
-
-  ////
-  //
-  // PROTECTED
-  //
-  ////
-  protected:
-
-    int                m_NRows;
-    int                m_NColumns;
-
-    MET_ValueEnumType  m_ElementType;
-
-    int                m_ElementNumberOfChannels;
-
-    bool               m_AutoFreeElementData;
-
-    unsigned int       m_CompressedElementDataSize;
-
-    char               m_ElementDataFileName[255];
-
-    void *             m_ElementData;
-
-    void  M_Destroy(void);
-
-    void  M_SetupReadFields(void);
-
-    void  M_SetupWriteFields(void);
-
-    bool  M_Read(void);
-
-    bool  M_ReadElements(METAIO_STREAM::ifstream * _fstream,
-                         void * _data,
-                         int _dataQuantity);
-
-    bool  M_WriteElements(METAIO_STREAM::ofstream * _fstream,
-                          const void * _data,
-                          int _dataQuantity);
-
-    };
-
-#if (METAIO_USE_NAMESPACE)
-};
-#endif
-
-#endif


Problem: server can segfault due to incomplete connections

(trying again -- the tests pass for me.  I'm not sure why they failed
before -- perhaps they have spurious failures?).

If the server is restarted and a client is still connected, it may
have a few CONNECTION_PING messages queued up on the socket which the
server will receive when it is restarted.  This is fine at the moment,
but in the case where the client does not then send CONNECTION_OPEN,
the server will try to deregister the client, and since the address
was never set, it segfaults.

Maybe this is only something I see because I'm working on a python
client and it's not well-behaved or something, but the server
shouldn't crash regardless, because even with well-behaved clients
this could happen if the client shuts down just after the server is
restarted.

Solution: cleanly handle the case of the client address being null.
Add a regression test.

--- src/mlm_server.c
+++ src/mlm_server.c
@@ -642,7 +642,9 @@
 static void
 client_expired (client_t *self)
 {
-    if (*self->address)
+    if (!self->address)
+        zsys_info ("client (incomplete connection) - expired");
+    else if (*self->address)
         zsys_info ("client address='%s' - expired", self->address);
 }

@@ -677,28 +679,33 @@
 static void
 deregister_the_client (client_t *self)
 {
-    if (*self->address)
-        zsys_info ("client address='%s' - de-registering", self->address);
-
-    //  Cancel all stream subscriptions
-    stream_t *stream = (stream_t *) zlistx_detach (self->readers, NULL);
-    while (stream) {
-        zsock_send (stream->actor, "sp", "CANCEL", self);
-        stream = (stream_t *) zlistx_detach (self->readers, NULL);
-    }
-    //  Cancel all service offerings
-    service_t *service = (service_t *) zhashx_first (self->server->services);
-    while (service) {
-        offer_t *offer = (offer_t *) zlistx_first (service->offers);
-        while (offer) {
-            if (offer->client == self)
-                zlistx_delete (service->offers, zlistx_cursor (service->offers));
-            offer = (offer_t *) zlistx_next (service->offers);
-        }
-        service = (service_t *) zhashx_next (self->server->services);
-    }
-    if (*self->address)
+	// If the client never sent CONNECTION_OPEN then self->address was
+	// never set, so avoid trying to dereference it.  Nothing needs to
+	// be cleaned up.
+	if (self->address) {
+		if (*self->address)
+			zsys_info ("client address='%s' - de-registering", self->address);
+
+		//  Cancel all stream subscriptions
+		stream_t *stream = (stream_t *) zlistx_detach (self->readers, NULL);
+		while (stream) {
+			zsock_send (stream->actor, "sp", "CANCEL", self);
+			stream = (stream_t *) zlistx_detach (self->readers, NULL);
+		}
+		//  Cancel all service offerings
+		service_t *service = (service_t *) zhashx_first (self->server->services);
+		while (service) {
+			offer_t *offer = (offer_t *) zlistx_first (service->offers);
+			while (offer) {
+				if (offer->client == self)
+					zlistx_delete (service->offers, zlistx_cursor (service->offers));
+				offer = (offer_t *) zlistx_next (service->offers);
+			}
+			service = (service_t *) zhashx_next (self->server->services);
+		}
+		if (*self->address)
         zhashx_delete (self->server->clients, self->address);
+	}
     mlm_proto_set_status_code (self->message, MLM_PROTO_SUCCESS);
 }

@@ -1089,6 +1096,39 @@
         zactor_destroy (&server);
     }

+    // Regression Test Case:
+    //      Segfault from deregistering zombie connection
+    {
+        const char *endpoint = "inproc://mlm_server_deregister_zombie_connection_test";
+        zactor_t *server = zactor_new (mlm_server, "mlm_server_deregister_zombie_connection_test");
+        if (verbose)
+            zstr_send (server, "VERBOSE");
+        zstr_sendx (server, "BIND", endpoint, NULL);
+        zstr_sendx (server, "SET", "server/timeout", "3000"); // 3 second client timeout
+
+        zsock_t *reader = zsock_new (ZMQ_DEALER);
+        assert (reader);
+        zsock_connect (reader, "inproc://mlm_server_deregister_zombie_connection_test");
+        zsock_set_rcvtimeo (reader, 500);
+
+        mlm_proto_t *proto = mlm_proto_new ();
+
+        // If the malamute server is restarted and clients have queued
+        // up ping messages, the'll be sent before any
+        // CONNECTION_OPEN.  The server eventually tries to deregister
+        // this and (previously) would derefence a null pointer for
+        // the client address.
+        mlm_proto_set_id (proto, MLM_PROTO_CONNECTION_PING);
+        mlm_proto_send (proto, reader);
+
+        printf("Regression test for segfault due to leftover client messages after restart...\n");
+        // Give the server more than 3 seconds to time out the client...
+        zclock_sleep (3100);
+        printf("passed\n");
+        zsock_destroy (&reader);
+        zactor_destroy (&server);
+    }
+
     //  @end
     printf ("OK\n");


[mod_webdav] compare COPY, MOVE Destination scheme

compare COPY, MOVE Destination scheme with request URI scheme

--- src/mod_webdav.c
+++ src/mod_webdav.c
@@ -1958,12 +1958,14 @@
 		 *  */

 		start = destination->ptr;
-
-		if (NULL == (sep = strstr(start, "://"))) {
+		sep = start + buffer_string_length(con->uri.scheme);
+
+		if (0 != strncmp(start, con->uri.scheme->ptr, sep - start)
+		    || sep[0] != ':' || sep[1] != '/' || sep[2] != '/') {
 			con->http_status = 400;
 			return HANDLER_FINISHED;
 		}
-		buffer_copy_string_len(p->uri.scheme, start, sep - start);
+		buffer_copy_buffer(p->uri.scheme, con->uri.scheme); /*(unused?)*/

 		start = sep + 3;


Comments

Comments

--- src/multivalue.h
+++ src/multivalue.h
@@ -31,6 +31,14 @@
 #include "htm.h"

+/*
+ * This class serializes a string vector.
+ * i.e
+ * StringList = {a, ..., b}
+ * values = encode_length(a.size()) + a + ... + encode_length(b.size()) + b
+ * symbol '+' means concatenate
+ * serialise = encode_length(values.size())values
+ */
 class StringList : public std::vector<std::string> {
 public:
 	void unserialise(const std::string & serialised);
@@ -40,6 +48,14 @@
 };

+/*
+ * This class serializes a Cartesian vector.
+ * i.e
+ * StringList = {a, ..., b}
+ * serialise = serialise_cartesian(a) + ... + serialise_cartesian(b)
+ * symbol '+' means concatenate.
+ * It is not necessary to save the size because it's SIZE_SERIALISE_CARTESIAN for all.
+ */
 class CartesianList : public std::vector<Cartesian> {
 public:
 	void unserialise(const std::string & serialised);
@@ -47,6 +63,14 @@
 };

+/*
+ * This class serializes a uInt64 vector.
+ * i.e
+ * StringList = {a, ..., b}
+ * serialise = serialise_geo(a) + ... + serialise_geo(b)
+ * symbol '+' means concatenate.
+ * It is not necessary to save the size because it's SIZE_BYTES_ID for all.
+ */
 class uInt64List : public std::vector<uInt64> {
 public:
 	void unserialise(const std::string & serialised);
@@ -186,8 +210,9 @@
 	Xapian::valueno slot;
 	double angle;

-	// Calculate if some their values is inside ranges.
+	// Calculates the smallest angle between its centroids  and search centroids.
 	void calc_angle(const std::string &serialised);
+	// Calculates if some their values is inside ranges.
 	bool insideRanges();

 	public:


Remove 'class' specifier.

Remove 'class' specifier.

git-svn-id: 0ff597fd157e6f4fc38580e8d64ab130330d2411@72113 91177308-0d34-0410-b5e6-96231b3b80d8

--- lib/CodeGen/Spiller.h
+++ lib/CodeGen/Spiller.h
@@ -22,12 +22,12 @@
   class Spiller {
   public:
     virtual ~Spiller() = 0;
-    virtual std::vector<LiveInterval*> spill(class LiveInterval *li) = 0;
+    virtual std::vector<LiveInterval*> spill(LiveInterval *li) = 0;
   };

   /// Create and return a spiller object, as specified on the command line.
-  Spiller* createSpiller(class MachineFunction *mf, class LiveIntervals *li,
-                         class VirtRegMap *vrm);
+  Spiller* createSpiller(MachineFunction *mf, LiveIntervals *li,
+                         VirtRegMap *vrm);
 }

 #endif


net: Fix set_macaddr func

net: Fix set_macaddr func

--- src/net/netdev.c
+++ src/net/netdev.c
@@ -161,7 +161,7 @@
 	}

 	assert(dev->drv_ops != NULL);
-	if (dev->drv_ops->set_macaddr == NULL) {
+	if (dev->drv_ops->set_macaddr != NULL) {
 		ret = dev->drv_ops->set_macaddr(dev, addr);
 		if (ret != 0) {
 			return ret;


Fixed comment.

Fixed comment.

--- src/ngx_python.c
+++ src/ngx_python.c
@@ -11,9 +11,8 @@
  * practice.  Python headers deliberately define the following macros:
  * _GNU_SOURCE, _POSIX_C_SOURCE, _XOPEN_SOURCE.
  * When compiling on Linux, they are defined by nginx or system headers
- * with Python possibly redefining them.  Since nginx is built with
- * -Werror compilation option, macros redefinition causes compilation
- * errors on some Linux systems.
+ * with Python possibly redefining them.  Since nginx is built with -Werror
+ * compilation option, macros redefinition causes compilation errors.
  */

 #include <ngx_config.h>


Document assumption about number of features with assertion

--- src/nnfeatures.c
+++ src/nnfeatures.c
@@ -14,6 +14,7 @@
  *  @return void
  **/
 void studentise_features(Mat_rptr features){
+	assert(4 == features->nr);
 	const int nevent = features->nc;

 	__m128 sum, sumsq;


bump version to 0.19.4

bump version to 0.19.4

--- src/nw_version.h
+++ src/nw_version.h
@@ -23,7 +23,7 @@

 #define NW_MAJOR_VERSION 0
 #define NW_MINOR_VERSION 19
-#define NW_PATCH_VERSION 3
+#define NW_PATCH_VERSION 4

 #define NW_VERSION_IS_RELEASE 1


bump version: 0.43.2

bump version: 0.43.2

--- src/nw_version.h
+++ src/nw_version.h
@@ -23,7 +23,7 @@

 #define NW_MAJOR_VERSION 0
 #define NW_MINOR_VERSION 43
-#define NW_PATCH_VERSION 1
+#define NW_PATCH_VERSION 2

 #define NW_VERSION_IS_RELEASE 1


simplified code with direct call to cambus_init

--- src/omv/sensor.c
+++ src/omv/sensor.c
@@ -237,44 +237,11 @@
     // Set default quality
     JPEG_FB()->quality = ((JPEG_QUALITY_HIGH - JPEG_QUALITY_LOW) / 2) + JPEG_QUALITY_LOW;

-#ifdef PORTENTA
-    I2C_HandleTypeDef i2c;
-    /* Configure I2C */
-
-    i2c.Instance             = SCCB_I2C;
-    i2c.Init.AddressingMode  = I2C_ADDRESSINGMODE_7BIT;
-    i2c.Init.Timing          = SCCB_TIMING;
-    i2c.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;
-    i2c.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;
-    i2c.Init.NoStretchMode   = I2C_NOSTRETCH_DISABLED;
-    i2c.Init.OwnAddress1     = 0xFE;
-    i2c.Init.OwnAddress2     = 0xFE;
-
-    HAL_I2C_Init(&i2c);
-
-    if (SCCB_TIMING == I2C_TIMING_FAST) {
-        // Enable FAST mode plus.
-        if (SCCB_I2C == I2C1) {
-            #if defined(I2C_FASTMODEPLUS_I2C1)
-            HAL_I2CEx_EnableFastModePlus(I2C_FASTMODEPLUS_I2C1);
-            #endif
-        } else if (SCCB_I2C == I2C2) {
-            #if defined(I2C_FASTMODEPLUS_I2C2)
-            HAL_I2CEx_EnableFastModePlus(I2C_FASTMODEPLUS_I2C2);
-            #endif
-        } else if (SCCB_I2C == I2C3) {
-            #if defined(I2C_FASTMODEPLUS_I2C3)
-            HAL_I2CEx_EnableFastModePlus(I2C_FASTMODEPLUS_I2C3);
-            #endif
-        } else {
-            #if defined(I2C_FASTMODEPLUS_I2C4)
-            HAL_I2CEx_EnableFastModePlus(I2C_FASTMODEPLUS_I2C4);
-            #endif
-        }
-    }
-#endif
     // Set fb_enabled
     JPEG_FB()->enabled = fb_enabled; // controlled by the IDE.
+#ifdef PORTENTA
+    cambus_init(&sensor.i2c, SCCB_I2C, SCCB_TIMING);
+#endif

 }


More portable handlig of directory access in pl-glob.c

--- src/os/pl-glob.c
+++ src/os/pl-glob.c
@@ -3,9 +3,10 @@
     Part of SWI-Prolog

     Author:        Jan Wielemaker
-    E-mail:        jan@swi.psy.uva.nl
+    E-mail:        J.Wielemaker@cs.vu.nl
     WWW:           http://www.swi-prolog.org
-    Copyright (C): 1985-2002, University of Amsterdam
+    Copyright (C): 1985-2011, University of Amsterdam
+			      VU University Amsterdam

     This library is free software; you can redistribute it and/or
     modify it under the terms of the GNU Lesser General Public
@@ -29,9 +30,9 @@
 #include <unistd.h>
 #endif

-#ifdef __WATCOMC__
-#include <direct.h>
-#else /*__WATCOMC__*/
+#ifdef O_XOS
+# include "windows/dirent.h"
+#else
 #if HAVE_DIRENT_H
 # include <dirent.h>
 #else
@@ -46,7 +47,7 @@
 #  include <ndir.h>
 # endif
 #endif
-#endif /*__WATCOMC__*/
+#endif /*O_XOS*/

 #ifdef HAVE_SYS_STAT_H
 #include <sys/stat.h>


Is --merge-lookups really necessary?

Is --merge-lookups really necessary?

--- src/otfccbuild.c
+++ src/otfccbuild.c
@@ -40,8 +40,8 @@
 	                "                               --ignore-glyph-order\n"
 	                "                               --short-post\n"
 	                "                               --merge-features\n"
-	                "     -O3                     Most aggressive opptimization strategy will be\n"
-	                "                             used. In this level, these options will be set:\n"
+	                // "     -O3                     Most aggressive opptimization strategy will be\n"
+	                // "                             used. In this level, these options will be set:\n"
 	                "                               --merge-lookups\n"
 	                " --time                    : Time each substep.\n"
 	                " --verbose                 : Show more information when building.\n\n"
@@ -213,7 +213,7 @@
 					options->cff_short_vmtx = true;
 					options->merge_features = true;
 				}
-				if (options->optimize_level >= 3) { options->merge_lookups = true; }
+				// if (options->optimize_level >= 3) { options->merge_lookups = true; }
 				break;
 		}
 	}


Replace gotos by transitions

Replace gotos by transitions

--- src/OVAL/probes/SEAP/sexp-parser.c
+++ src/OVAL/probes/SEAP/sexp-parser.c
@@ -678,10 +678,10 @@
                          * expression.
                          */
                         if (__predict(cur_c < 128, 1))
-                                goto laddr(cur_c);
+                                dfa_state = d_states[cur_c];
                         else
-                                goto L_INVALID;
-                        /* NOTREACHED */
+                                dfa_state = S_INVALID;
+                        break;

                 L_CHAR:
                 case S_CHAR:


Interpret constant-width fonts as being "literal" (i.e., non-smartypants) mode.

--- nroff_smartypants.c
+++ nroff_smartypants.c
@@ -330,14 +330,12 @@
 	size_t	 	 i = 0;
 	const uint8_t	*cp;

-	/* FIXME: code span */
-
 	if ((0 == previous_char || '\n' == previous_char) &&
-	    (size >= 3 && 0 == memcmp(text + 1, "DS\n", 3))) {
-		i = 3;
+	    (size >= 6 && 0 == memcmp(text + 1, "ft CR\n", 6))) {
+		i = 6;
 		hbuf_put(ob, text, i);
 		/* FIXME: check size - i >= 4 */
-		cp = memmem(text + i, size - i, "\n.DE\n", 4);
+		cp = memmem(text + i, size - i, "\n.ft\n", 4);
 		assert(NULL != cp);
 		hbuf_put(ob, text + i, cp - (text + i));
 		i += cp - (text + i) - 1;


fix too strict assertion (issue #204)

fix too strict assertion (issue #204)

--- src/page-queue.c
+++ src/page-queue.c
@@ -339,8 +339,10 @@
   // set append pages to new heap and count
   size_t count = 0;
   for (mi_page_t* page = append->first; page != NULL; page = page->next) {
-    mi_page_set_heap(page,heap);
-    // set it to delayed free (not overriding NEVER_DELAYED_FREE) which has as a
+    // inline `mi_page_set_heap` to avoid wrong assertion during absorption;
+    // in this case it is ok to be delayed freeing since both "to" and "from" heap are still alive.
+    mi_atomic_write(&page->xheap, (uintptr_t)heap);
+    // set the flag to delayed free (not overriding NEVER_DELAYED_FREE) which has as a
     // side effect that it spins until any DELAYED_FREEING is finished. This ensures
     // that after appending only the new heap will be used for delayed free operations.
     _mi_page_use_delayed_free(page, MI_USE_DELAYED_FREE, false);


Adjusting buffer size for more balanced performance.

--- SearchEngine/FileReadWorkQueue.h
+++ SearchEngine/FileReadWorkQueue.h
@@ -22,8 +22,9 @@
     void DrainWorkQueue();
     void CompleteAllWork();

-    static constexpr uint16_t kFileReadSlotCount = DSTORAGE_MAX_QUEUE_CAPACITY;
-    static constexpr size_t kFileReadBufferBaseSize = 512 * 1024 * 1024 / kFileReadSlotCount; // 512 MB total
+    static constexpr size_t kTargetTotalBufferSize = 512 * 1024 * 1024; // 512 MB total
+    static constexpr size_t kFileReadBufferBaseSize = 128 * 1024;
+    static constexpr uint16_t kFileReadSlotCount = kTargetTotalBufferSize / kFileReadBufferBaseSize;

 private:
     typedef WorkQueue<FileReadData> MyFileReadBase;


iref-array link with meta

iref-array link with meta

--- code/foundation/util/iarraytypes.c
+++ code/foundation/util/iarraytypes.c
@@ -324,6 +324,9 @@

 /* array-iref with user config, index the change */
 iarray* iarraymakeirefwithentry(size_t capacity, const irefarrayentry *refentry) {
+    if (!_arr_entry_iref.elemeta) {
+        ((iarrayentry*)&_arr_entry_iref)->elemeta = imetaof(irefptr);
+    }
     iarray*  arr = iarraymake(capacity, &_arr_entry_iref);
     arr->userdata = (void*)refentry;
     return arr;
@@ -347,6 +350,7 @@
     entry->swap = _iarray_entry_swap_iref;
     entry->assign = _iarray_entry_assign_iref;
     entry->cmp = cmp;
+    entry->elemeta = imetaof(irefptr);

     arr = iarraymake(capacity, entry);
     arr->userdata = (void*)refentry;


SCCS xml.c 10/09/03 08:14:26: date and time created 10/09/03 08:14:26 by neo

error: pathspec 'src/pbasis/xml.c' did not match any file(s) known to git

--- src/pbasis/xml.c
+++ src/pbasis/xml.c
@@ -0,0 +1,1009 @@
+/* -MODULE----------------------------------------------------------------------
+Phorward Foundation Libraries :: Basis Library
+Copyright (C) 2006-2010 by Phorward Software Technologies, Jan Max Meyer
+http://www.phorward-software.com ++ contact<at>phorward<dash>software<dot>com
+All rights reserved. See $PHOME/LICENSE for more information.n.
+
+File:	xml.c
+Author:	Aaron Voisine, contributions by Jan Max Meyer
+Usage:	XML processing functions (based on ezXML)
+----------------------------------------------------------------------------- */
+
+/* xml.c
+ *
+ * Copyright 2004-2006 Aaron Voisine <aaron@voisine.org>
+ *
+ * Permission is hereby granted, free of ucharge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Includes
+ */
+#include "pbasis.h"
+
+/*
+ * Global variables
+ */
+
+/*
+ * Defines
+ */
+
+/*
+ * Functions
+ */
+
+#define XML_WS   "\t\r\n "  /* whitespace */
+#define XML_ERRL 128        /* maximum error string length */
+
+typedef struct xml_root *xml_root_t;
+struct xml_root {       /* additional data for the root tag */
+    struct xml xml;     /* is a super-struct built on top of xml struct */
+    XML_T cur;          /* current xml tree insertion point */
+    uchar *m;              /* original xml string */
+    size_t len;           /* length of allocated memory for mmap, -1 for malloc */
+    uchar *u;              /* UTF-8 conversion of string if original was UTF-16 */
+    uchar *s;              /* start of work area */
+    uchar *e;              /* end of work area */
+    uchar **ent;           /* general entities (ampersand sequences) */
+    uchar ***attr;         /* default attributes */
+    uchar ***pi;           /* processing instructions */
+    short standalone;     /* non-zero if <?xml standalone="yes"?> */
+    uchar err[XML_ERRL]; /* error string */
+};
+
+uchar *XML_NIL[] = { NULL }; /* empty, null terminated array of strings */
+
+/* returns the first child tag with the given name or NULL if not found */
+XML_T xml_child(XML_T xml, const uchar *name)
+{
+    xml = (xml) ? xml->child : NULL;
+    while (xml && strcmp(name, xml->name)) xml = xml->sibling;
+    return xml;
+}
+
+/* returns the Nth tag with the same name in the same subsection
+	or NULL if not */
+/* found */
+XML_T xml_idx(XML_T xml, int idx)
+{
+    for (; xml && idx; idx--) xml = xml->next;
+    return xml;
+}
+
+/* returns the value of the requested tag attribute or NULL if not found */
+const uchar *xml_attr(XML_T xml, const uchar *attr)
+{
+    int i = 0, j = 1;
+    xml_root_t root = (xml_root_t)xml;
+
+    if (! xml || ! xml->attr) return NULL;
+    while (xml->attr[i] && strcmp(attr, xml->attr[i])) i += 2;
+    if (xml->attr[i]) return xml->attr[i + 1]; /* found attribute */
+
+    while (root->xml.parent) root = (xml_root_t)root->xml.parent; /* root tag */
+    for (i = 0; root->attr[i] && strcmp(xml->name, root->attr[i][0]); i++);
+    if (! root->attr[i]) return NULL; /* no matching default attributes */
+    while (root->attr[i][j] && strcmp(attr, root->attr[i][j])) j += 3;
+    return (root->attr[i][j]) ? root->attr[i][j + 1] : NULL; /* found default */
+}
+
+/* same as xml_get but takes an already initialized va_list */
+XML_T xml_vget(XML_T xml, va_list ap)
+{
+    uchar *name = va_arg(ap, uchar *);
+    int idx = -1;
+
+    if (name && *name) {
+        idx = va_arg(ap, int);
+        xml = xml_child(xml, name);
+    }
+    return (idx < 0) ? xml : xml_vget(xml_idx(xml, idx), ap);
+}
+
+/* Traverses the xml tree to retrieve a specific subtag. Takes a variable */
+/* length list of tag names and indexes. The argument list must be terminated */
+/* by either an index of -1 or an empty string tag name. Example:  */
+/* title = xml_get(library, "shelf", 0, "book", 2, "title", -1); */
+/* This retrieves the title of the 3rd book on the 1st shelf of library. */
+/* Returns NULL if not found. */
+XML_T xml_get(XML_T xml, ...)
+{
+    va_list ap;
+    XML_T r;
+
+    va_start(ap, xml);
+    r = xml_vget(xml, ap);
+    va_end(ap);
+    return r;
+}
+
+/* returns a null terminated array of processing instructions for the given */
+/* target */
+const uchar **xml_pi(XML_T xml, const uchar *target)
+{
+    xml_root_t root = (xml_root_t)xml;
+    int i = 0;
+
+    if (! root) return (const uchar **)XML_NIL;
+    while (root->xml.parent) root = (xml_root_t)root->xml.parent; /* root tag */
+    while (root->pi[i] && strcmp(target, root->pi[i][0])) i++; /* find target */
+    return (const uchar **)((root->pi[i]) ? root->pi[i] + 1 : XML_NIL);
+}
+
+/* set an error string and return root */
+static XML_T xml_err(xml_root_t root, uchar *s, const uchar *err, ...)
+{
+    va_list ap;
+    int line = 1;
+    uchar *t, fmt[XML_ERRL];
+
+    for (t = root->s; t < s; t++) if (*t == '\n') line++;
+#ifdef _WIN32
+    _snprintf
+#else
+    snprintf
+#endif
+	(fmt, XML_ERRL, "[error near line %d]: %s", line, err);
+
+    va_start(ap, err);
+#ifdef _WIN32
+    _vsnprintf
+#else
+    vsnprintf
+#endif
+	(root->err, XML_ERRL, fmt, ap);
+    va_end(ap);
+
+    return &root->xml;
+}
+
+/* Recursively decodes entity and character references and normalizes new lines */
+/* ent is a null terminated array of alternating entity names and values. set t */
+/* to '&' for general entity decoding, '%' for parameter entity decoding, 'c' */
+/* for cdata sections, ' ' for attribute normalization, or '*' for non-cdata */
+/* attribute normalization. Returns s, or if the decoded string is longer than */
+/* s, returns a malloced string that must be freed. */
+uchar *xml_decode(uchar *s, uchar **ent, uchar t)
+{
+    uchar *e, *r = s, *m = s;
+    long b, c, d, l;
+
+    for (; *s; s++) { /* normalize line endings */
+        while (*s == '\r') {
+            *(s++) = '\n';
+            if (*s == '\n') memmove(s, (s + 1), strlen(s));
+        }
+    }
+
+    for (s = r; ; ) {
+        while (*s && *s != '&' && (*s != '%' || t != '%') && !isspace(*s)) s++;
+
+        if (! *s) break;
+        else if (t != 'c' && ! strncmp(s, "&#", 2)) { /* character reference */
+            if (s[2] == 'x') c = strtol(s + 3, &e, 16); /* base 16 */
+            else c = strtol(s + 2, &e, 10); /* base 10 */
+            if (! c || *e != ';') { s++; continue; } /* not a character ref */
+
+            if (c < 0x80) *(s++) = (uchar) c; /* US-ASCII subset */
+            else { /* multi-byte UTF-8 sequence */
+                for (b = 0, d = c; d; d /= 2) b++; /* number of bits in c */
+                b = (b - 2) / 5; /* number of bytes in payload */
+                *(s++) = (uchar) ((0xFF << (7 - b)) | (c >> (6 * b))); /* head */
+                while (b) *(s++) = (uchar) (0x80 | ((c >> (6 * --b)) & 0x3F)); /* payload */
+            }
+
+            memmove(s, strchr(s, ';') + 1, strlen(strchr(s, ';')));
+        }
+        else if ((*s == '&' && (t == '&' || t == ' ' || t == '*')) ||
+                 (*s == '%' && t == '%')) { /* entity reference */
+            for (b = 0; ent[b] && strncmp(s + 1, ent[b], strlen(ent[b]));
+                 b += 2); /* find entity in entity list */
+
+            if (ent[b++]) { /* found a match */
+                if ((c = strlen(ent[b])) - 1 > (e = strchr(s, ';')) - s) {
+                    l = (d = (s - r)) + c + strlen(e); /* new length */
+                    r = (r == m) ? strcpy(malloc(l), r) : realloc(r, l);
+                    e = strchr((s = r + d), ';'); /* fix up pointers */
+                }
+
+                memmove(s + c, e + 1, strlen(e)); /* shift rest of string */
+                strncpy(s, ent[b], c); /* copy in replacement text */
+            }
+            else s++; /* not a known entity */
+        }
+        else if ((t == ' ' || t == '*') && isspace(*s)) *(s++) = ' ';
+        else s++; /* no decoding needed */
+    }
+
+    if (t == '*') { /* normalize spaces for non-cdata attributes */
+        for (s = r; *s; s++) {
+            if ((l = strspn(s, " "))) memmove(s, s + l, strlen(s + l) + 1);
+            while (*s && *s != ' ') s++;
+        }
+        if (--s >= r && *s == ' ') *s = '\0'; /* trim any trailing space */
+    }
+    return r;
+}
+
+/* called when parser finds start of new tag */
+static void xml_open_tag(xml_root_t root, uchar *name, uchar **attr)
+{
+    XML_T xml = root->cur;
+
+    if (xml->name) xml = xml_add_child(xml, name, strlen(xml->txt));
+    else xml->name = name; /* first open tag */
+
+    xml->attr = attr;
+    root->cur = xml; /* update tag insertion point */
+}
+
+/* called when parser finds character content between open and closing tag */
+static void xml_uchar_content(xml_root_t root, uchar *s, size_t len, uchar t)
+{
+    XML_T xml = root->cur;
+    uchar *m = s;
+    size_t l;
+
+    if (! xml || ! xml->name || ! len) return; /* sanity check */
+
+    s[len] = '\0'; /* null terminate text (calling functions anticipate this) */
+    len = strlen(s = xml_decode(s, root->ent, t)) + 1;
+
+    if (! *(xml->txt)) xml->txt = s; /* initial character content */
+    else { /* allocate our own memory and make a copy */
+        xml->txt = (xml->flags & XML_TXTM) /* allocate some space */
+                   ? realloc(xml->txt, (l = strlen(xml->txt)) + len)
+                   : strcpy(malloc((l = strlen(xml->txt)) + len), xml->txt);
+        strcpy(xml->txt + l, s); /* add new uchar content */
+        if (s != m) free(s); /* free s if it was malloced by xml_decode() */
+    }
+
+    if (xml->txt != m) xml_set_flag(xml, XML_TXTM);
+}
+
+/* called when parser finds closing tag */
+static XML_T xml_close_tag(xml_root_t root, uchar *name, uchar *s)
+{
+    if (! root->cur || ! root->cur->name || strcmp(name, root->cur->name))
+        return xml_err(root, s, "unexpected closing tag </%s>", name);
+
+    root->cur = root->cur->parent;
+    return NULL;
+}
+
+/* checks for circular entity references, returns non-zero if no circular */
+/* references are found, zero otherwise */
+static int xml_ent_ok(uchar *name, uchar *s, uchar **ent)
+{
+    int i;
+
+    for (; ; s++) {
+        while (*s && *s != '&') s++; /* find next entity reference */
+        if (! *s) return 1;
+        if (! strncmp(s + 1, name, strlen(name))) return 0; /* circular ref. */
+        for (i = 0; ent[i] && strncmp(ent[i], s + 1, strlen(ent[i])); i += 2);
+        if (ent[i] && ! xml_ent_ok(name, ent[i + 1], ent)) return 0;
+    }
+}
+
+/* called when the parser finds a processing instruction */
+static void xml_proc_inst(xml_root_t root, uchar *s, size_t len)
+{
+    int i = 0, j = 1;
+    uchar *target = s;
+
+    s[len] = '\0'; /* null terminate instruction */
+    if (*(s += strcspn(s, XML_WS))) {
+        *s = '\0'; /* null terminate target */
+        s += strspn(s + 1, XML_WS) + 1; /* skip whitespace after target */
+    }
+
+    if (! strcmp(target, "xml")) { /* <?xml ... ?> */
+        if ((s = strstr(s, "standalone")) && ! strncmp(s + strspn(s + 10,
+            XML_WS "='\"") + 10, "yes", 3)) root->standalone = 1;
+        return;
+    }
+
+    if (! root->pi[0]) *(root->pi = malloc(sizeof(uchar **))) = NULL; /*first pi */
+
+    while (root->pi[i] && strcmp(target, root->pi[i][0])) i++; /* find target */
+    if (! root->pi[i]) { /* new target */
+        root->pi = realloc(root->pi, sizeof(uchar **) * (i + 2));
+        root->pi[i] = malloc(sizeof(uchar *) * 3);
+        root->pi[i][0] = target;
+        root->pi[i][1] = (uchar *)(root->pi[i + 1] = NULL); /* terminate pi list */
+        root->pi[i][2] = strdup(""); /* empty document position list */
+    }
+
+    while (root->pi[i][j]) j++; /* find end of instruction list for this target */
+    root->pi[i] = realloc(root->pi[i], sizeof(uchar *) * (j + 3));
+    root->pi[i][j + 2] = realloc(root->pi[i][j + 1], j + 1);
+    strcpy(root->pi[i][j + 2] + j - 1, (root->xml.name) ? ">" : "<");
+    root->pi[i][j + 1] = NULL; /* null terminate pi list for this target */
+    root->pi[i][j] = s; /* set instruction */
+}
+
+/* called when the parser finds an internal doctype subset */
+static short xml_internal_dtd(xml_root_t root, uchar *s, size_t len)
+{
+    uchar q, *c, *t, *n = NULL, *v, **ent, **pe;
+    int i, j;
+
+    pe = memcpy(malloc(sizeof(XML_NIL)), XML_NIL, sizeof(XML_NIL));
+
+    for (s[len] = '\0'; s; ) {
+        while (*s && *s != '<' && *s != '%') s++; /* find next declaration */
+
+        if (! *s) break;
+        else if (! strncmp(s, "<!ENTITY", 8)) { /* parse entity definitions */
+            c = s += strspn(s + 8, XML_WS) + 8; /* skip white space separator */
+            n = s + strspn(s, XML_WS "%"); /* find name */
+            *(s = n + strcspn(n, XML_WS)) = ';'; /* append ; to name */
+
+            v = s + strspn(s + 1, XML_WS) + 1; /* find value */
+            if ((q = *(v++)) != '"' && q != '\'') { /* skip externals */
+                s = strchr(s, '>');
+                continue;
+            }
+
+            for (i = 0, ent = (*c == '%') ? pe : root->ent; ent[i]; i++);
+            ent = realloc(ent, (i + 3) * sizeof(uchar *)); /* space for next ent */
+            if (*c == '%') pe = ent;
+            else root->ent = ent;
+
+            *(++s) = '\0'; /* null terminate name */
+            if ((s = strchr(v, q))) *(s++) = '\0'; /* null terminate value */
+            ent[i + 1] = xml_decode(v, pe, '%'); /* set value */
+            ent[i + 2] = NULL; /* null terminate entity list */
+            if (! xml_ent_ok(n, ent[i + 1], ent)) { /* circular reference */
+                if (ent[i + 1] != v) free(ent[i + 1]);
+                xml_err(root, v, "circular entity declaration &%s", n);
+                break;
+            }
+            else ent[i] = n; /* set entity name */
+        }
+        else if (! strncmp(s, "<!ATTLIST", 9)) { /* parse default attributes */
+            t = s + strspn(s + 9, XML_WS) + 9; /* skip whitespace separator */
+            if (! *t) { xml_err(root, t, "unclosed <!ATTLIST"); break; }
+            if (*(s = t + strcspn(t, XML_WS ">")) == '>') continue;
+            else *s = '\0'; /* null terminate tag name */
+            for (i = 0; root->attr[i] && strcmp(n, root->attr[i][0]); i++);
+
+            while (*(n = ++s + strspn(s, XML_WS)) && *n != '>') {
+                if (*(s = n + strcspn(n, XML_WS))) *s = '\0'; /* attr name */
+                else { xml_err(root, t, "malformed <!ATTLIST"); break; }
+
+                s += strspn(s + 1, XML_WS) + 1; /* find next token */
+                c = (strncmp(s, "CDATA", 5)) ? "*" : " "; /* is it cdata? */
+                if (! strncmp(s, "NOTATION", 8))
+                    s += strspn(s + 8, XML_WS) + 8;
+                s = (*s == '(') ? strchr(s, ')') : s + strcspn(s, XML_WS);
+                if (! s) { xml_err(root, t, "malformed <!ATTLIST"); break; }
+
+                s += strspn(s, XML_WS ")"); /* skip white space separator */
+                if (! strncmp(s, "#FIXED", 6))
+                    s += strspn(s + 6, XML_WS) + 6;
+                if (*s == '#') { /* no default value */
+                    s += strcspn(s, XML_WS ">") - 1;
+                    if (*c == ' ') continue; /* cdata is default, nothing to do */
+                    v = NULL;
+                }
+                else if ((*s == '"' || *s == '\'')  &&  /* default value */
+                         (s = strchr(v = s + 1, *s))) *s = '\0';
+                else { xml_err(root, t, "malformed <!ATTLIST"); break; }
+
+                if (! root->attr[i]) { /* new tag name */
+                    root->attr = (! i) ? malloc(2 * sizeof(uchar **))
+                                       : realloc(root->attr,
+                                                 (i + 2) * sizeof(uchar **));
+                    root->attr[i] = malloc(2 * sizeof(uchar *));
+                    root->attr[i][0] = t; /* set tag name */
+                    root->attr[i][1] = (uchar *)(root->attr[i + 1] = NULL);
+                }
+
+                for (j = 1; root->attr[i][j]; j += 3); /* find end of list */
+                root->attr[i] = realloc(root->attr[i],
+                                        (j + 4) * sizeof(uchar *));
+
+                root->attr[i][j + 3] = NULL; /* null terminate list */
+                root->attr[i][j + 2] = c; /* is it cdata? */
+                root->attr[i][j + 1] = (v) ? xml_decode(v, root->ent, *c)
+                                           : NULL;
+                root->attr[i][j] = n; /* attribute name  */
+            }
+        }
+        else if (! strncmp(s, "<!--", 4)) s = strstr(s + 4, "-->"); /* comments */
+        else if (! strncmp(s, "<?", 2)) { /* processing instructions */
+            if ((s = strstr(c = s + 2, "?>")))
+                xml_proc_inst(root, c, s++ - c);
+        }
+        else if (*s == '<') s = strchr(s, '>'); /* skip other declarations */
+        else if (*(s++) == '%' && ! root->standalone) break;
+    }
+
+    free(pe);
+    return ! *root->err;
+}
+
+/* Converts a UTF-16 string to UTF-8. Returns a new string that must be freed */
+/* or NULL if no conversion was needed. */
+uchar *xml_str2utf8(uchar **s, size_t *len)
+{
+    uchar *u;
+    size_t l = 0, sl, max = *len;
+    long c, d;
+    int b, be = (**s == '\xFE') ? 1 : (**s == '\xFF') ? 0 : -1;
+
+    if (be == -1) return NULL; /* not UTF-16 */
+
+    u = malloc(max);
+    for (sl = 2; sl < *len - 1; sl += 2) {
+        c = (be) ? (((*s)[sl] & 0xFF) << 8) | ((*s)[sl + 1] & 0xFF)  /*UTF-16BE */
+                 : (((*s)[sl + 1] & 0xFF) << 8) | ((*s)[sl] & 0xFF); /*UTF-16LE */
+        if (c >= 0xD800 && c <= 0xDFFF && (sl += 2) < *len - 1) { /* high-half */
+            d = (be) ? (((*s)[sl] & 0xFF) << 8) | ((*s)[sl + 1] & 0xFF)
+                     : (((*s)[sl + 1] & 0xFF) << 8) | ((*s)[sl] & 0xFF);
+            c = (((c & 0x3FF) << 10) | (d & 0x3FF)) + 0x10000;
+        }
+
+        while (l + 6 > max) u = realloc(u, max += XML_BUFSIZE);
+        if (c < 0x80) u[l++] = (uchar) c; /* US-ASCII subset */
+        else { /* multi-byte UTF-8 sequence */
+            for (b = 0, d = c; d; d /= 2) b++; /* bits in c */
+            b = (b - 2) / 5; /* bytes in payload */
+            u[l++] = (uchar) ((0xFF << (7 - b)) | (c >> (6 * b))); /* head */
+            while (b) u[l++] = (uchar) (0x80 | ((c >> (6 * --b)) & 0x3F)); /* payload */
+        }
+    }
+    return *s = realloc(u, *len = l);
+}
+
+/* frees a tag attribute list */
+void xml_free_attr(uchar **attr) {
+    int i = 0;
+    uchar *m;
+
+    if (! attr || attr == XML_NIL) return; /* nothing to free */
+    while (attr[i]) i += 2; /* find end of attribute list */
+    m = attr[i + 1]; /* list of which names and values are malloced */
+    for (i = 0; m[i]; i++) {
+        if (m[i] & XML_NAMEM) free(attr[i * 2]);
+        if (m[i] & XML_TXTM) free(attr[(i * 2) + 1]);
+    }
+    free(m);
+    free(attr);
+}
+
+/* parse the given xml string and return an xml structure */
+XML_T xml_parse_str(uchar *s, size_t len)
+{
+    xml_root_t root = (xml_root_t)xml_new(NULL);
+    uchar q, e, *d, **attr, **a = NULL; /* initialize a to avoid compile warning */
+    int l, i, j;
+
+    root->m = s;
+    if (! len) return xml_err(root, NULL, "root tag missing");
+    root->u = xml_str2utf8(&s, &len); /* convert utf-16 to utf-8 */
+    root->e = (root->s = s) + len; /* record start and end of work area */
+
+    e = s[len - 1]; /* save end uchar */
+    s[len - 1] = '\0'; /* turn end uchar into null terminator */
+
+    while (*s && *s != '<') s++; /* find first tag */
+    if (! *s) return xml_err(root, s, "root tag missing");
+
+    for (; ; ) {
+        attr = (uchar **)XML_NIL;
+        d = ++s;
+
+        if (isalpha(*s) || *s == '_' || *s == ':' || *s < '\0') { /* new tag */
+            if (! root->cur)
+                return xml_err(root, d, "markup outside of root element");
+
+            s += strcspn(s, XML_WS "/>");
+            while (isspace(*s)) *(s++) = '\0'; /* null terminate tag name */
+
+            if (*s && *s != '/' && *s != '>') /* find tag in default attr list */
+                for (i = 0; (a = root->attr[i]) && strcmp(a[0], d); i++);
+
+            for (l = 0; *s && *s != '/' && *s != '>'; l += 2) { /* new attrib */
+                attr = (l) ? realloc(attr, (l + 4) * sizeof(uchar *))
+                           : malloc(4 * sizeof(uchar *)); /* allocate space */
+                attr[l + 3] = (l) ? realloc(attr[l + 1], (l / 2) + 2)
+                                  : malloc(2); /* mem for list of maloced vals */
+                strcpy(attr[l + 3] + (l / 2), " "); /* value is not malloced */
+                attr[l + 2] = NULL; /* null terminate list */
+                attr[l + 1] = ""; /* temporary attribute value */
+                attr[l] = s; /* set attribute name */
+
+                s += strcspn(s, XML_WS "=/>");
+                if (*s == '=' || isspace(*s)) {
+                    *(s++) = '\0'; /* null terminate tag attribute name */
+                    q = *(s += strspn(s, XML_WS "="));
+                    if (q == '"' || q == '\'') { /* attribute value */
+                        attr[l + 1] = ++s;
+                        while (*s && *s != q) s++;
+                        if (*s) *(s++) = '\0'; /* null terminate attribute val */
+                        else {
+                            xml_free_attr(attr);
+                            return xml_err(root, d, "missing %c", q);
+                        }
+
+                        for (j = 1; a && a[j] && strcmp(a[j], attr[l]); j +=3);
+                        attr[l + 1] = xml_decode(attr[l + 1], root->ent, (a
+                                                   && a[j]) ? *a[j + 2] : ' ');
+                        if (attr[l + 1] < d || attr[l + 1] > s)
+                            attr[l + 3][l / 2] = XML_TXTM; /* value malloced */
+                    }
+                }
+                while (isspace(*s)) s++;
+            }
+
+            if (*s == '/') { /* self closing tag */
+                *(s++) = '\0';
+                if ((*s && *s != '>') || (! *s && e != '>')) {
+                    if (l) xml_free_attr(attr);
+                    return xml_err(root, d, "missing >");
+                }
+                xml_open_tag(root, d, attr);
+                xml_close_tag(root, d, s);
+            }
+            else if ((q = *s) == '>' || (! *s && e == '>')) { /* open tag */
+                *s = '\0'; /* temporarily null terminate tag name */
+                xml_open_tag(root, d, attr);
+                *s = q;
+            }
+            else {
+                if (l) xml_free_attr(attr);
+                return xml_err(root, d, "missing >");
+            }
+        }
+        else if (*s == '/') { /* close tag */
+            s += strcspn(d = s + 1, XML_WS ">") + 1;
+            if (! (q = *s) && e != '>') return xml_err(root, d, "missing >");
+            *s = '\0'; /* temporarily null terminate tag name */
+            if (xml_close_tag(root, d, s)) return &root->xml;
+            if (isspace(*s = q)) s += strspn(s, XML_WS);
+        }
+        else if (! strncmp(s, "!--", 3)) { /* xml comment */
+            if (! (s = strstr(s + 3, "--")) || (*(s += 2) != '>' && *s) ||
+                (! *s && e != '>')) return xml_err(root, d, "unclosed <!--");
+        }
+        else if (! strncmp(s, "![CDATA[", 8)) { /* cdata */
+            if ((s = strstr(s, "]]>")))
+                xml_uchar_content(root, d + 8, (s += 2) - d - 10, 'c');
+            else return xml_err(root, d, "unclosed <![CDATA[");
+        }
+        else if (! strncmp(s, "!DOCTYPE", 8)) { /* dtd */
+            for (l = 0; *s && ((! l && *s != '>') || (l && (*s != ']' ||
+                 *(s + strspn(s + 1, XML_WS) + 1) != '>')));
+                 l = (*s == '[') ? 1 : l) s += strcspn(s + 1, "[]>") + 1;
+            if (! *s && e != '>')
+                return xml_err(root, d, "unclosed <!DOCTYPE");
+            d = (l) ? strchr(d, '[') + 1 : d;
+            if (l && ! xml_internal_dtd(root, d, s++ - d)) return &root->xml;
+        }
+        else if (*s == '?') { /* <?...?> processing instructions */
+            do { s = strchr(s, '?'); } while (s && *(++s) && *s != '>');
+            if (! s || (! *s && e != '>'))
+                return xml_err(root, d, "unclosed <?");
+            else xml_proc_inst(root, d + 1, s - d - 2);
+        }
+        else return xml_err(root, d, "unexpected <");
+
+        if (! s || ! *s) break;
+        *s = '\0';
+        d = ++s;
+        if (*s && *s != '<') { /* tag character content */
+            while (*s && *s != '<') s++;
+            if (*s) xml_uchar_content(root, d, s - d, '&');
+            else break;
+        }
+        else if (! *s) break;
+    }
+
+    if (! root->cur) return &root->xml;
+    else if (! root->cur->name) return xml_err(root, d, "root tag missing");
+    else return xml_err(root, d, "unclosed tag <%s>", root->cur->name);
+}
+
+/* Wrapper for xml_parse_str() that accepts a file stream. Reads the entire */
+/* stream into memory and then parses it. For xml files, use xml_parse_file() */
+/* or xml_parse_fd() */
+XML_T xml_parse_fp(FILE *fp)
+{
+    xml_root_t root;
+    size_t l, len = 0;
+    uchar *s;
+
+    if (! (s = malloc(XML_BUFSIZE))) return NULL;
+    do {
+        len += (l = fread((s + len), 1, XML_BUFSIZE, fp));
+        if (l == XML_BUFSIZE) s = realloc(s, len + XML_BUFSIZE);
+    } while (s && l == XML_BUFSIZE);
+
+    if (! s) return NULL;
+    root = (xml_root_t)xml_parse_str(s, len);
+    root->len = -1; /* so we know to free s in xml_free() */
+    return &root->xml;
+}
+
+/* A wrapper for xml_parse_str() that accepts a file descriptor. First */
+/* attempts to mem map the file. Failing that, reads the file into memory. */
+/* Returns NULL on failure. */
+XML_T xml_parse_fd(int fd)
+{
+    xml_root_t root;
+    struct stat st;
+    size_t l;
+    void *m;
+
+    if (fd < 0) return NULL;
+    fstat(fd, &st);
+
+    l = read(fd, m = malloc(st.st_size), st.st_size);
+    root = (xml_root_t)xml_parse_str(m, l);
+    root->len = -1; /* so we know to free s in xml_free() */
+
+    return &root->xml;
+}
+
+/* a wrapper for xml_parse_fd that accepts a file name */
+XML_T xml_parse_file(const uchar *file)
+{
+    int fd = open(file, O_RDONLY, 0);
+    XML_T xml = xml_parse_fd(fd);
+
+    if (fd >= 0) close(fd);
+    return xml;
+}
+
+/* Encodes ampersand sequences appending the results to *dst, reallocating *dst */
+/* if length excedes max. a is non-zero for attribute encoding. Returns *dst */
+uchar *xml_ampencode(const uchar *s, size_t len, uchar **dst, size_t *dlen,
+                      size_t *max, short a)
+{
+    const uchar *e;
+
+    for (e = s + len; s != e; s++) {
+        while (*dlen + 10 > *max) *dst = realloc(*dst, *max += XML_BUFSIZE);
+
+        switch (*s) {
+        case '\0': return *dst;
+        case '&': *dlen += sprintf(*dst + *dlen, "&"); break;
+        case '<': *dlen += sprintf(*dst + *dlen, "<"); break;
+        case '>': *dlen += sprintf(*dst + *dlen, ">"); break;
+        case '"': *dlen += sprintf(*dst + *dlen, (a) ? """ : "\""); break;
+        case '\n': *dlen += sprintf(*dst + *dlen, (a) ? "
" : "\n"); break;
+        case '\t': *dlen += sprintf(*dst + *dlen, (a) ? "	" : "\t"); break;
+        case '\r': *dlen += sprintf(*dst + *dlen, "
"); break;
+        default: (*dst)[(*dlen)++] = *s;
+        }
+    }
+    return *dst;
+}
+
+/* Recursively converts each tag to xml appending it to *s. Reallocates *s if */
+/* its length excedes max. start is the location of the previous tag in the */
+/* parent tag's character content. Returns *s. */
+uchar *XML_Toxml_r(XML_T xml, uchar **s, size_t *len, size_t *max,
+                    size_t start, uchar ***attr)
+{
+    int i, j;
+    uchar *txt = (xml->parent) ? xml->parent->txt : "";
+    size_t off = 0;
+
+    /* parent character content up to this tag */
+    *s = xml_ampencode(txt + start, xml->off - start, s, len, max, 0);
+
+    while (*len + strlen(xml->name) + 4 > *max) /* reallocate s */
+        *s = realloc(*s, *max += XML_BUFSIZE);
+
+    *len += sprintf(*s + *len, "<%s", xml->name); /* open tag */
+    for (i = 0; xml->attr[i]; i += 2) { /* tag attributes */
+        if (xml_attr(xml, xml->attr[i]) != xml->attr[i + 1]) continue;
+        while (*len + strlen(xml->attr[i]) + 7 > *max) /* reallocate s */
+            *s = realloc(*s, *max += XML_BUFSIZE);
+
+        *len += sprintf(*s + *len, " %s=\"", xml->attr[i]);
+        xml_ampencode(xml->attr[i + 1], -1, s, len, max, 1);
+        *len += sprintf(*s + *len, "\"");
+    }
+
+    for (i = 0; attr[i] && strcmp(attr[i][0], xml->name); i++);
+    for (j = 1; attr[i] && attr[i][j]; j += 3) { /* default attributes */
+        if (! attr[i][j + 1] || xml_attr(xml, attr[i][j]) != attr[i][j + 1])
+            continue; /* skip duplicates and non-values */
+        while (*len + strlen(attr[i][j]) + 7 > *max) /* reallocate s */
+            *s = realloc(*s, *max += XML_BUFSIZE);
+
+        *len += sprintf(*s + *len, " %s=\"", attr[i][j]);
+        xml_ampencode(attr[i][j + 1], -1, s, len, max, 1);
+        *len += sprintf(*s + *len, "\"");
+    }
+    *len += sprintf(*s + *len, ">");
+
+    *s = (xml->child) ? XML_Toxml_r(xml->child, s, len, max, 0, attr) /*child */
+                      : xml_ampencode(xml->txt, -1, s, len, max, 0);  /*data */
+
+    while (*len + strlen(xml->name) + 4 > *max) /* reallocate s */
+        *s = realloc(*s, *max += XML_BUFSIZE);
+
+    *len += sprintf(*s + *len, "</%s>", xml->name); /* close tag */
+
+    while (txt[off] && off < xml->off) off++; /* make sure off is within bounds */
+    return (xml->ordered) ? XML_Toxml_r(xml->ordered, s, len, max, off, attr)
+                          : xml_ampencode(txt + off, -1, s, len, max, 0);
+}
+
+/* Converts an xml structure back to xml. Returns a string of xml data that */
+/* must be freed. */
+uchar *XML_Toxml(XML_T xml)
+{
+    XML_T p = (xml) ? xml->parent : NULL, o = (xml) ? xml->ordered : NULL;
+    xml_root_t root = (xml_root_t)xml;
+    size_t len = 0, max = XML_BUFSIZE;
+    uchar *s = strcpy(malloc(max), ""), *t, *n;
+    int i, j, k;
+
+    if (! xml || ! xml->name) return realloc(s, len + 1);
+    while (root->xml.parent) root = (xml_root_t)root->xml.parent; /* root tag */
+
+    for (i = 0; ! p && root->pi[i]; i++) { /* pre-root processing instructions */
+        for (k = 2; root->pi[i][k - 1]; k++);
+        for (j = 1; (n = root->pi[i][j]); j++) {
+            if (root->pi[i][k][j - 1] == '>') continue; /* not pre-root */
+            while (len + strlen(t = root->pi[i][0]) + strlen(n) + 7 > max)
+                s = realloc(s, max += XML_BUFSIZE);
+            len += sprintf(s + len, "<?%s%s%s?>\n", t, *n ? " " : "", n);
+        }
+    }
+
+    xml->parent = xml->ordered = NULL;
+    s = XML_Toxml_r(xml, &s, &len, &max, 0, root->attr);
+    xml->parent = p;
+    xml->ordered = o;
+
+    for (i = 0; ! p && root->pi[i]; i++) { /* post-root processing instructions */
+        for (k = 2; root->pi[i][k - 1]; k++);
+        for (j = 1; (n = root->pi[i][j]); j++) {
+            if (root->pi[i][k][j - 1] == '<') continue; /* not post-root */
+            while (len + strlen(t = root->pi[i][0]) + strlen(n) + 7 > max)
+                s = realloc(s, max += XML_BUFSIZE);
+            len += sprintf(s + len, "\n<?%s%s%s?>", t, *n ? " " : "", n);
+        }
+    }
+    return realloc(s, len + 1);
+}
+
+/* free the memory allocated for the xml structure */
+void xml_free(XML_T xml)
+{
+    xml_root_t root = (xml_root_t)xml;
+    int i, j;
+    uchar **a, *s;
+
+    if (! xml) return;
+    xml_free(xml->child);
+    xml_free(xml->ordered);
+
+    if (! xml->parent) { /* free root tag allocations */
+        for (i = 10; root->ent[i]; i += 2) /* 0 - 9 are default entites (<>&"') */
+            if ((s = root->ent[i + 1]) < root->s || s > root->e) free(s);
+        free(root->ent); /* free list of general entities */
+
+        for (i = 0; (a = root->attr[i]); i++) {
+            for (j = 1; a[j++]; j += 2) /* free malloced attribute values */
+                if (a[j] && (a[j] < root->s || a[j] > root->e)) free(a[j]);
+            free(a);
+        }
+        if (root->attr[0]) free(root->attr); /* free default attribute list */
+
+        for (i = 0; root->pi[i]; i++) {
+            for (j = 1; root->pi[i][j]; j++);
+            free(root->pi[i][j + 1]);
+            free(root->pi[i]);
+        }
+        if (root->pi[0]) free(root->pi); /* free processing instructions */
+
+        if (root->len == -1) free(root->m); /* malloced xml data */
+        if (root->u) free(root->u); /* utf8 conversion */
+    }
+
+    xml_free_attr(xml->attr); /* tag attributes */
+    if ((xml->flags & XML_TXTM)) free(xml->txt); /* character content */
+    if ((xml->flags & XML_NAMEM)) free(xml->name); /* tag name */
+    free(xml);
+}
+
+/* return parser error message or empty string if none */
+const uchar *xml_error(XML_T xml)
+{
+    while (xml && xml->parent) xml = xml->parent; /* find root tag */
+    return (xml) ? ((xml_root_t)xml)->err : "";
+}
+
+/* returns a new empty xml structure with the given root tag name */
+XML_T xml_new(const uchar *name)
+{
+    static uchar *ent[] = { "lt;", "<", "gt;", ">", "quot;", """,
+                           "apos;", "'", "amp;", "&", NULL };
+    xml_root_t root = (xml_root_t)memset(malloc(sizeof(struct xml_root)),
+                                             '\0', sizeof(struct xml_root));
+    root->xml.name = (uchar *)name;
+    root->cur = &root->xml;
+    strcpy(root->err, root->xml.txt = "");
+    root->ent = memcpy(malloc(sizeof(ent)), ent, sizeof(ent));
+    root->attr = root->pi = (uchar ***)(root->xml.attr = XML_NIL);
+    return &root->xml;
+}
+
+/* inserts an existing tag into an xml structure */
+XML_T xml_insert(XML_T xml, XML_T dest, size_t off)
+{
+    XML_T cur, prev, head;
+
+    xml->next = xml->sibling = xml->ordered = NULL;
+    xml->off = off;
+    xml->parent = dest;
+
+    if ((head = dest->child)) { /* already have sub tags */
+        if (head->off <= off) { /* not first subtag */
+            for (cur = head; cur->ordered && cur->ordered->off <= off;
+                 cur = cur->ordered);
+            xml->ordered = cur->ordered;
+            cur->ordered = xml;
+        }
+        else { /* first subtag */
+            xml->ordered = head;
+            dest->child = xml;
+        }
+
+        for (cur = head, prev = NULL; cur && strcmp(cur->name, xml->name);
+             prev = cur, cur = cur->sibling); /* find tag type */
+        if (cur && cur->off <= off) { /* not first of type */
+            while (cur->next && cur->next->off <= off) cur = cur->next;
+            xml->next = cur->next;
+            cur->next = xml;
+        }
+        else { /* first tag of this type */
+            if (prev && cur) prev->sibling = cur->sibling; /* remove old first */
+            xml->next = cur; /* old first tag is now next */
+            for (cur = head, prev = NULL; cur && cur->off <= off;
+                 prev = cur, cur = cur->sibling); /* new sibling insert point */
+            xml->sibling = cur;
+            if (prev) prev->sibling = xml;
+        }
+    }
+    else dest->child = xml; /* only sub tag */
+
+    return xml;
+}
+
+/* Adds a child tag. off is the offset of the child tag relative to the start */
+/* of the parent tag's character content. Returns the child tag. */
+XML_T xml_add_child(XML_T xml, const uchar *name, size_t off)
+{
+    XML_T child;
+
+    if (! xml) return NULL;
+    child = (XML_T)memset(malloc(sizeof(struct xml)), '\0',
+                            sizeof(struct xml));
+    child->name = (uchar *)name;
+    child->attr = XML_NIL;
+    child->txt = "";
+
+    return xml_insert(child, xml, off);
+}
+
+/* sets the character content for the given tag and returns the tag */
+XML_T xml_set_txt(XML_T xml, const uchar *txt)
+{
+    if (! xml) return NULL;
+    if (xml->flags & XML_TXTM) free(xml->txt); /* existing txt was malloced */
+    xml->flags &= ~XML_TXTM;
+    xml->txt = (uchar *)txt;
+    return xml;
+}
+
+/* Sets the given tag attribute or adds a new attribute if not found. A value */
+/* of NULL will remove the specified attribute. Returns the tag given. */
+XML_T xml_set_attr(XML_T xml, const uchar *name, const uchar *value)
+{
+    int l = 0, c;
+
+    if (! xml) return NULL;
+    while (xml->attr[l] && strcmp(xml->attr[l], name)) l += 2;
+    if (! xml->attr[l]) { /* not found, add as new attribute */
+        if (! value) return xml; /* nothing to do */
+        if (xml->attr == XML_NIL) { /* first attribute */
+            xml->attr = malloc(4 * sizeof(uchar *));
+            xml->attr[1] = strdup(""); /* empty list of malloced names/vals */
+        }
+        else xml->attr = realloc(xml->attr, (l + 4) * sizeof(uchar *));
+
+        xml->attr[l] = (uchar *)name; /* set attribute name */
+        xml->attr[l + 2] = NULL; /* null terminate attribute list */
+        xml->attr[l + 3] = realloc(xml->attr[l + 1],
+                                   (c = strlen(xml->attr[l + 1])) + 2);
+        strcpy(xml->attr[l + 3] + c, " "); /* set name/value as not malloced */
+        if (xml->flags & XML_DUP) xml->attr[l + 3][c] = XML_NAMEM;
+    }
+    else if (xml->flags & XML_DUP) free((uchar *)name); /* name was strduped */
+
+    for (c = l; xml->attr[c]; c += 2); /* find end of attribute list */
+    if (xml->attr[c + 1][l / 2] & XML_TXTM) free(xml->attr[l + 1]); /*old val */
+    if (xml->flags & XML_DUP) xml->attr[c + 1][l / 2] |= XML_TXTM;
+    else xml->attr[c + 1][l / 2] &= ~XML_TXTM;
+
+    if (value) xml->attr[l + 1] = (uchar *)value; /* set attribute value */
+    else { /* remove attribute */
+        if (xml->attr[c + 1][l / 2] & XML_NAMEM) free(xml->attr[l]);
+        memmove(xml->attr + l, xml->attr + l + 2, (c - l + 2) * sizeof(uchar*));
+        xml->attr = realloc(xml->attr, (c + 2) * sizeof(uchar *));
+        memmove(xml->attr[c + 1] + (l / 2), xml->attr[c + 1] + (l / 2) + 1,
+                (c / 2) - (l / 2)); /* fix list of which name/vals are malloced */
+    }
+    xml->flags &= ~XML_DUP; /* clear strdup() flag */
+    return xml;
+}
+
+/* sets a flag for the given tag and returns the tag */
+XML_T xml_set_flag(XML_T xml, short flag)
+{
+    if (xml) xml->flags |= flag;
+    return xml;
+}
+
+/* removes a tag along with its subtags without freeing its memory */
+XML_T xml_cut(XML_T xml)
+{
+    XML_T cur;
+
+    if (! xml) return NULL; /* nothing to do */
+    if (xml->next) xml->next->sibling = xml->sibling; /* patch sibling list */
+
+    if (xml->parent) { /* not root tag */
+        cur = xml->parent->child; /* find head of subtag list */
+        if (cur == xml) xml->parent->child = xml->ordered; /* first subtag */
+        else { /* not first subtag */
+            while (cur->ordered != xml) cur = cur->ordered;
+            cur->ordered = cur->ordered->ordered; /* patch ordered list */
+
+            cur = xml->parent->child; /* go back to head of subtag list */
+            if (strcmp(cur->name, xml->name)) { /* not in first sibling list */
+                while (strcmp(cur->sibling->name, xml->name))
+                    cur = cur->sibling;
+                if (cur->sibling == xml) { /* first of a sibling list */
+                    cur->sibling = (xml->next) ? xml->next
+                                               : cur->sibling->sibling;
+                }
+                else cur = cur->sibling; /* not first of a sibling list */
+            }
+
+            while (cur->next && cur->next != xml) cur = cur->next;
+            if (cur->next) cur->next = cur->next->next; /* patch next list */
+        }
+    }
+    xml->ordered = xml->sibling = xml->next = NULL;
+    return xml;
+}
+


main(): do not fail if pcscd.comm is already present but pcscd.pid is
not present.

This is the case if pcscd has been configured in systemd but has been
stoped. When launched by hand (for a debug session for example) the
pcscd.comm file is still present but not used anymore.

The pcscd.comm file will be removed when pcscd manually started will
exit but the file will be recreated by "systemctl start pcscd.service"

git-svn-id: f2d781e409b7e36a714fc884bb9b2fc5091ddd28@6072 0ce88b0d-b2fd-0310-8134-9614164e65ea

--- src/pcscdaemon.c
+++ src/pcscdaemon.c
@@ -385,20 +385,6 @@
 			{
 				Log1(PCSC_LOG_CRITICAL, "file " PCSCLITE_RUN_PID " do not exist");
 				Log1(PCSC_LOG_CRITICAL, "Hotplug failed");
-				return EXIT_FAILURE;
-			}
-
-			if (!SocketActivated)
-			{
-				Log1(PCSC_LOG_CRITICAL,
-					"file " PCSCLITE_CSOCK_NAME " already exists.");
-				Log1(PCSC_LOG_CRITICAL,
-					"Maybe another pcscd is running?");
-				Log1(PCSC_LOG_CRITICAL,
-					"I can't read process pid from " PCSCLITE_RUN_PID);
-				Log1(PCSC_LOG_CRITICAL, "Remove " PCSCLITE_CSOCK_NAME);
-				Log1(PCSC_LOG_CRITICAL,
-					"if pcscd is not running to clear this message.");
 				return EXIT_FAILURE;
 			}
 		}


2 typos

2 typos

git-svn-id: f2d781e409b7e36a714fc884bb9b2fc5091ddd28@2680 0ce88b0d-b2fd-0310-8134-9614164e65ea

--- src/pcscdaemon.c
+++ src/pcscdaemon.c
@@ -603,7 +603,7 @@
 	printf("  -f, --foreground	run in foreground (no daemon),\n");
 	printf("			send logs to stderr instead of syslog\n");
 	printf("  -h, --help		display usage information\n");
-	printf("  -H, --hotplug		ask the daemon to rescan the avaiable readers\n");
+	printf("  -H, --hotplug		ask the daemon to rescan the available readers\n");
 	printf("  -v, --version		display the program version number\n");
 	printf("  -d, --debug	 	display lower level debug messages\n");
 	printf("      --info	 	display info level debug messages (default level)\n");
@@ -616,7 +616,7 @@
 	printf("  -f	run in foreground (no daemon), send logs to stderr instead of syslog\n");
 	printf("  -d 	display debug messages. Output may be:\n");
 	printf("  -h 	display usage information\n");
-	printf("  -H	ask the daemon to rescan the avaiable readers\n");
+	printf("  -H	ask the daemon to rescan the available readers\n");
 	printf("  -v 	display the program version number\n");
 #endif
 }


*** empty log message ***

*** empty log message ***

--- lib/common/postproc.c
+++ lib/common/postproc.c
@@ -96,8 +96,8 @@

     if (ED_spl(e) == NULL) {
 	if ((Concentrate == FALSE) || (ED_edge_type(e) != IGNORED))
-	    agerr(AGERR, "lost %s %s edge\n",agnameof(agtail(e)),
-		  agnameof(aghead(e)));
+	    agerr(AGERR, "lost %s %s edge\n",agnameof(agtail(e)),
+		  agnameof(aghead(e)));
 	return;
     }
     for (j = 0; j < ED_spl(e)->size; j++) {
@@ -285,7 +285,7 @@
 #ifndef WITH_CGRAPH
     if ((g != g->root) && (GD_label(g)) && !GD_label(g)->set) {
 #else /* WITH_CGRAPH */
-    if ((g != agroot(g)) && (GD_label(g)) && !GD_label(g)->set) {
+    if ((g != agroot(g)) && (GD_label(g)) && !GD_label(g)->set) {
 #endif /* WITH_CGRAPH */

 	if (GD_label_pos(g) & LABEL_AT_TOP) {
@@ -325,7 +325,7 @@
 #ifndef WITH_CGRAPH
     if ((g != g->root) && (GD_label(g)) && !GD_label(g)->set) {
 #else /* WITH_CGRAPH */
-    if ((g != agroot(g)) && (GD_label(g)) && !GD_label(g)->set) {
+    if ((g != agroot(g)) && (GD_label(g)) && !GD_label(g)->set) {
 #endif /* WITH_CGRAPH */
 	if (GD_label_pos(g) & LABEL_AT_TOP) {
 	    d = GD_border(g)[TOP_IX];


fs: Add reiserfs and f2fs checks to bd_fs_check_deps

I forgot to add these when adding support for these filesystems.

--- src/plugins/fs.c
+++ src/plugins/fs.c
@@ -104,6 +104,25 @@
         bd_utils_log_format (BD_UTILS_LOG_WARNING, "%s", error->message);
         g_clear_error (&error);
     }
+    ret = ret && bd_fs_f2fs_is_tech_avail (BD_FS_TECH_F2FS,
+                                           BD_FS_TECH_MODE_MKFS | BD_FS_TECH_MODE_WIPE |
+                                           BD_FS_TECH_MODE_CHECK | BD_FS_TECH_MODE_REPAIR |
+                                           BD_FS_TECH_MODE_QUERY | BD_FS_TECH_MODE_RESIZE,
+                                           &error);
+    if (!ret && error) {
+        bd_utils_log_format (BD_UTILS_LOG_WARNING, "%s", error->message);
+        g_clear_error (&error);
+    }
+    ret = ret && bd_fs_reiserfs_is_tech_avail (BD_FS_TECH_REISERFS,
+                                               BD_FS_TECH_MODE_MKFS | BD_FS_TECH_MODE_WIPE |
+                                               BD_FS_TECH_MODE_CHECK | BD_FS_TECH_MODE_REPAIR |
+                                               BD_FS_TECH_MODE_SET_LABEL | BD_FS_TECH_MODE_QUERY |
+                                               BD_FS_TECH_MODE_RESIZE | BD_FS_TECH_MODE_SET_UUID,
+                                               &error);
+    if (!ret && error) {
+        bd_utils_log_format (BD_UTILS_LOG_WARNING, "%s", error->message);
+        g_clear_error (&error);
+    }
     return ret;
 }


Add _NULLOK() to an ARGIN macro and add a cast to pacify the compiler.

git-svn-id: febc16327e28fa443313d1a69d2b37af6ca9976c@43086 d31e2699-5ff4-0310-a27c-f18f2fbe73fe

--- src/pmc_freeze.c
+++ src/pmc_freeze.c
@@ -147,10 +147,9 @@

 static void todo_list_init(PARROT_INTERP,
     ARGOUT(visit_info *info),
-    ARGIN(STRING *input))
+    ARGIN_NULLOK(STRING *input))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
-        __attribute__nonnull__(3)
         FUNC_MODIFIES(*info);

 PARROT_INLINE
@@ -235,8 +234,7 @@
     , PARROT_ASSERT_ARG(type))
 #define ASSERT_ARGS_todo_list_init __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(info) \
-    , PARROT_ASSERT_ARG(input))
+    , PARROT_ASSERT_ARG(info))
 #define ASSERT_ARGS_todo_list_seen __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(pmc) \
@@ -577,8 +575,9 @@
 */

 static void
-todo_list_init(PARROT_INTERP, ARGOUT(visit_info *info), ARGIN(STRING *input))
-{
+todo_list_init(PARROT_INTERP, ARGOUT(visit_info *info), ARGIN_NULLOK(STRING *input))
+{
+    ASSERT_ARGS(todo_list_init)
     /* We want to store a 16-byte aligned header, but the actual
      * header may be shorter. */
     const unsigned int header_length = PACKFILE_HEADER_BYTES +
@@ -620,7 +619,7 @@

         info->buffer = (Buffer *)input;
         PARROT_ASSERT(input->_bufstart == input->strstart);
-        info->pos = Buffer_bufstart(info->buffer);
+        info->pos = (char *) Buffer_bufstart(info->buffer);
         info->input_length = input->strlen;
         mem_sys_memcopy(pf->header, info->pos, PACKFILE_HEADER_BYTES);


In ft_init(): declared header_length to be unsigned

git-svn-id: 6e74a02f85675cec270f5d931b0f6998666294a3@20390 d31e2699-5ff4-0310-a27c-f18f2fbe73fe

--- src/pmc_freeze.c
+++ src/pmc_freeze.c
@@ -852,7 +852,7 @@

     /* We want to store a 16-byte aligned header, but the actual
      * header may be shorter. */
-    const int header_length = PACKFILE_HEADER_BYTES +
+    const unsigned int header_length = PACKFILE_HEADER_BYTES +
         (PACKFILE_HEADER_BYTES % 16 ?
          16 - PACKFILE_HEADER_BYTES % 16 : 0);