Changes to the log interface

Changes to the log interface

--- src/log.h
+++ src/log.h
@@ -21,31 +21,47 @@
    */
   class log {
     public:
-      log(const std::string & trace, int verbosity = 0);
+      enum loglevel {
+        none = -1,
+        info,
+        warn,
+        err
+      };
+
+      log(const std::string & trace = std::string(), loglevel verbosity = info);
       ~log();

       template <typename T>
-      inline log & operator()(const T&, int verbosity = -1);
+      inline log & operator()(const T&, loglevel verbosity = info);
       template <typename T1, typename T2>
-      inline log & operator()(const T1&, const T2&, int verbosity = -1);
+      inline log & operator()(const T1&, const T2&, loglevel verbosity = info);
       template <typename T1, typename T2, typename T3>
-      inline log & operator()(const T1&, const T2&, const T3&, int verbosity = -1);
+      inline log & operator()(const T1&, const T2&, const T3&, loglevel verbosity = info);
       template <typename T1, typename T2, typename T3, typename T4>
-      inline log & operator()(const T1&, const T2&, const T3&, const T4&, int verbosity = -1);
+      inline log & operator()(const T1&, const T2&, const T3&, const T4&, loglevel verbosity = info);
       template <typename T1, typename T2, typename T3, typename T4, typename T5>
-      inline log & operator()(const T1&, const T2&, const T3&, const T4&, const T5&, int verbosity = -1);
+      inline log & operator()(const T1&, const T2&, const T3&, const T4&, const T5&, loglevel verbosity = info);
       template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
-      inline log & operator()(const T1&, const T2&, const T3&, const T4&, const T5&, const T6&, int verbosity = -1);
+      inline log & operator()(const T1&, const T2&, const T3&, const T4&, const T5&, const T6&, loglevel verbosity = info);

       static void output(const std::string & filename, bool append=false);
       static void output(std::ostream &);

+
     public:
-      static int verbosity;
+      static loglevel level;

     private:
       static int indent;
       static std::ostream logstream;
+
+    private:
+      std::string trace;
+      loglevel verbosity;
+
   };
 }
+
+#define tracelog \
+  gear2d::log trace(__PRETTY_FUNCTION__, log::info);
 #endif


fix buttons cxform

fix buttons cxform

--- src/lvg.c
+++ src/lvg.c
@@ -639,6 +639,7 @@
                         continue;
                     g_render->set_transform(g_render_obj, bs->obj.t, 0);
                     LVGColorTransform newcxform = *cxform;
+                    combine_cxform(&newcxform, &o->cxform, 1.0);
                     combine_cxform(&newcxform, &bs->obj.cxform, alpha*btn_alpha);
                     lvgDrawShape(&clip->shapes[bs->obj.id], &newcxform, bs->obj.ratio/65535.0f, blend_mode);
                     g_render->set_transform(g_render_obj, save_t, 1);


doc: document the length requirements of output parameter.

It's subtle, since it is actually only touched by hashfp (though
we assert it's non-NULL), but give explicit advice in the default
case.

Signed-off-by: Rusty Russell <df9728c9e5104131c08c7adb03af425394842596@rustcorp.com.au>

--- include/secp256k1_ecdh.h
+++ include/secp256k1_ecdh.h
@@ -22,22 +22,25 @@
   void *data
 );

-/** An implementation of SHA256 hash function that applies to compressed public key. */
+/** An implementation of SHA256 hash function that applies to compressed public key.
+ * Populates the output parameter with 32 bytes. */
 SECP256K1_API extern const secp256k1_ecdh_hash_function secp256k1_ecdh_hash_function_sha256;

-/** A default ecdh hash function (currently equal to secp256k1_ecdh_hash_function_sha256). */
+/** A default ecdh hash function (currently equal to secp256k1_ecdh_hash_function_sha256).
+ * Populates the output parameter with 32 bytes. */
 SECP256K1_API extern const secp256k1_ecdh_hash_function secp256k1_ecdh_hash_function_default;

 /** Compute an EC Diffie-Hellman secret in constant time
  *  Returns: 1: exponentiation was successful
  *           0: scalar was invalid (zero or overflow)
  *  Args:    ctx:        pointer to a context object (cannot be NULL)
- *  Out:     output:     pointer to an array to be filled by the function
+ *  Out:     output:     pointer to an array to be filled by hashfp
  *  In:      pubkey:     a pointer to a secp256k1_pubkey containing an
  *                       initialized public key
  *           privkey:    a 32-byte scalar with which to multiply the point
  *           hashfp:     pointer to a hash function. If NULL, secp256k1_ecdh_hash_function_sha256 is used
- *           data:       Arbitrary data pointer that is passed through
+ *                       (in which case, 32 bytes will be written to output)
+ *           data:       Arbitrary data pointer that is passed through to hashfp
  */
 SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdh(
   const secp256k1_context* ctx,


Constants names should be uppercase to distinghush them.

--- src/mbc.c
+++ src/mbc.c
@@ -7,7 +7,7 @@
 #include <libmbc.h>

 static const char* CLI_VERSION = "0.1";
-static char* cli_name; // will be set by main()
+static char* CLI_NAME; // will be set by main()
 static const char* USAGE_OPT = "(-e | -d) -k key [-x] [-v] [-h]";
 static const char* HELP_MSG =
 	"mbc is a quick tool for encoding/decoding data from stdio using the libmbc\n"
@@ -78,11 +78,11 @@
 }

 void print_version() {
-	fprintf(stderr, "%s %s\n", cli_name, CLI_VERSION);
+	fprintf(stderr, "%s %s\n", CLI_NAME, CLI_VERSION);
 }

 void print_usage() {
-	fprintf(stderr, "Usage: %s %s\n", cli_name, USAGE_OPT);
+	fprintf(stderr, "Usage: %s %s\n", CLI_NAME, USAGE_OPT);
 }

 void print_help() {
@@ -97,7 +97,6 @@
 }

 int main(int argc, char* argv[]) {
-
 	char opt;
 	char* key;
 	bool enc_flag, dec_flag, mode_set, hex_mode;
@@ -108,7 +107,7 @@
 	dec_flag = false;
 	mode_set = false;

-	cli_name = argv[0];
+	CLI_NAME = argv[0];

 	while ((opt = getopt(argc, argv, "edk:xvh")) != -1) {
 		switch (opt) {
@@ -152,5 +151,4 @@
 	mbc_core(enc_flag, key, hex_mode);

 	return 0;
-
 }


edit _stack_alloc

edit _stack_alloc

--- src/mem.h
+++ src/mem.h
@@ -69,11 +69,11 @@
                                                                                \
 STATEMENT_                                                                     \
 (                                                                              \
-    unsigned char _alloc = _it_xl_total((_ccxll), _itxl_);                     \
+    unsigned char _total = _it_xl_total((_ccxll), _itxl_);                     \
                                                                                \
     _stack_alloc((_ccxll), (_items), (_pbase), _itxl_);                        \
                                                                                \
-    for (int _idx = _alloc; _idx < *(_pbase) + (_items); _idx++)               \
+    for (int _idx = _total; _idx < *(_pbase) + (_items); _idx++)               \
         _pinit((_ccxll)->_itxl_[_idx], (_ccxll));                              \
 )

@@ -99,9 +99,9 @@
                                                                                \
 STATEMENT_                                                                     \
 (                                                                              \
-    unsigned char _it_alloc = _it_xl_total((_ccxll), _it);                     \
-                                                                               \
-    for (int _idx_it = 0; _idx_it < _it_alloc; _idx_it++)                      \
+    unsigned char _it_total = _it_xl_total((_ccxll), _it);                     \
+                                                                               \
+    for (int _idx_it = 0; _idx_it < _it_total; _idx_it++)                      \
         _iter_free((_ccxll)->_it[_idx_it]);                                    \
                                                                                \
     _stack_free((_ccxll), _it);                                                \
@@ -112,9 +112,9 @@
                                                                                \
 STATEMENT_                                                                     \
 (                                                                              \
-    unsigned char _xl_alloc = _it_xl_total((_ccxll), _xl);                     \
-                                                                               \
-    for (int _idx_xl = 0; _idx_xl < _xl_alloc; _idx_xl++)                      \
+    unsigned char _xl_total = _it_xl_total((_ccxll), _xl);                     \
+                                                                               \
+    for (int _idx_xl = 0; _idx_xl < _xl_total; _idx_xl++)                      \
     {                                                                          \
         _it_free((_ccxll)->_xl[_idx_xl]);                                      \
         _block_free((_ccxll)->_xl[_idx_xl]);                                   \
@@ -135,18 +135,14 @@
 (                                                                              \
     if ((_items) > (_ccxll)->_itxl_##_limit && (_items) != 0)                  \
     {                                                                          \
-        void  *_list = NULL;                                                   \
-        size_t _sz   = sizeof(*(_ccxll)->_itxl_);                              \
-                                                                               \
-        _safe_alloc(_list, _sz * ((_ccxll)->_itxl_##_base + (_items)));        \
-                                                                               \
-        memcpy(_list, (_ccxll)->_itxl_, _sz * (_ccxll)->_itxl_##_base);        \
-                                                                               \
-        if (_it_xl_total((_ccxll), _itxl_) != 0)                               \
-            _safe_free((_ccxll)->_itxl_);                                      \
-        (_ccxll)->_itxl_ = _list;                                              \
-                                                                               \
-        memset((_ccxll)->_itxl_ + (_ccxll)->_itxl_##_base, 0, _sz * (_items)); \
+        size_t _size = sizeof(*(_ccxll)->_itxl_);                              \
+        unsigned char _itxl_total = _it_xl_total((_ccxll), _itxl_);            \
+                                                                               \
+        void **_tmp = (void*)&((_ccxll)->_itxl_);                              \
+        *_tmp = realloc(*_tmp, (_size * ((_ccxll)->_itxl_##_base + (_items))));\
+                                                                               \
+        memset((_ccxll)->_itxl_ + _itxl_total, 0,                              \
+               (_size * ((_ccxll)->_itxl_##_base + (_items) - _itxl_total)));  \
                                                                                \
         (_ccxll)->_itxl_##_limit = (_items);                                   \
     }                                                                          \


Add declarations for message-driven PDO processing

--- include/socanmatic/pdo.h
+++ include/socanmatic/pdo.h
@@ -53,6 +53,29 @@
 #define CANMAT_RPDO_COM_COB_ID       0x1
 #define CANMAT_RPDO_COM_TRANS_TYPE   0x2

+
+struct pdo_descriptor {
+    uint32_t cob_id;          ///< CAN frame COB-ID
+    unsigned n_obj : 4;       ///< number of objects in the PDO
+    struct {
+        unsigned offset : 3;  ///< offset in frame data for this PDO
+        unsigned size   : 3;  ///< size of the object, range 1-4
+        void *ptr;            ///< pointer to where we should store the object
+    } obj[8];
+};
+
+struct pdo_descriptor_table {
+    size_t n;             ///< number of valid entries
+    size_t max;           ///< allocated size of descriptor
+    struct pdo_descriptor_table *descriptor; ///< pointer to the entries
+};
+
+/** Lookup the descriptor for can_frame in and write message data to the pointed location.
+ *
+ */
+enum canmat_status canmat_pdo_process(
+    const struct pdo_descriptor_table table, const struct can_frame );
+
 #ifdef __cplusplus
 }
 #endif


Added moc.h (MOC infos on status bar)

Added moc.h (MOC infos on status bar)

error: pathspec 'src/moc.h' did not match any file(s) known to git

--- src/moc.h
+++ src/moc.h
@@ -0,0 +1,33 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+int is_moc_running() {
+
+	char *return_code = calloc(2, sizeof(char));
+	FILE *pgrep_stdout = popen("pgrep moc > /dev/null; echo $?", "r");
+
+	fgets(return_code, sizeof(return_code), pgrep_stdout);
+
+	pclose(pgrep_stdout);
+
+	if(return_code[0]=='0') return 1;
+	return 0;
+}
+
+char *get_moc_infos() {
+
+	if(is_moc_running()) {
+		char *infos = calloc(128, sizeof(char));
+		FILE *mocp_stdout = popen("mocp -Q \"%state: %title %ct/%tl [%tt]\"", "r");
+
+		fgets(infos, 128, mocp_stdout);
+
+		pclose(mocp_stdout);
+
+		infos[strlen(infos)-1] = '\0';
+
+		if(infos[0]=='S') return "STOP";
+		return infos;
+	}
+	else return "STOP";
+}


core: Fix not removing old schema

core: Fix not removing old schema

This patch fixes an error when an existent 'schema' is updated.
The current implementation was appending the submitted schema instead
of replacing it.

--- src/msg.c
+++ src/msg.c
@@ -48,7 +48,8 @@
 struct trust {
 	char *uuid;			/* Device UUID */
 	char *token;			/* Device token */
-	GSList *schema;			/* List of knot_schema */
+	GSList *schema;			/* knot_schema accepted by cloud */
+	GSList *schema_tmp;		/* knot_schema to be submitted to cloud */
 };

 /* Maps sockets to sessions  */
@@ -59,6 +60,7 @@
 	g_free(trust->uuid);
 	g_free(trust->token);
 	g_slist_free_full(trust->schema, g_free);
+	g_slist_free_full(trust->schema_tmp, g_free);
 	g_free(trust);
 }

@@ -395,8 +397,9 @@
 	 *	]
 	 */

+	/* Add to a temporary list until receiving complete schema */
 	kschema = g_memdup(schema, sizeof(*schema));
-	trust->schema = g_slist_append(trust->schema, kschema);
+	trust->schema_tmp = g_slist_append(trust->schema_tmp, kschema);

 	 /* TODO: missing timer to wait for end of schema transfer */

@@ -408,7 +411,7 @@
 	schemajobj = json_object_new_object();

 	/* Creating an array if the sensor supports multiple data types */
-	for (list = trust->schema; list; list = g_slist_next(list)) {
+	for (list = trust->schema_tmp; list; list = g_slist_next(list)) {
 		schema = list->data;
 		jobj = json_object_new_object();
 		json_object_object_add(jobj, "sensor_id",
@@ -433,9 +436,16 @@
 	json_object_put(schemajobj);

 	if (err < 0) {
+		g_slist_free_full(trust->schema_tmp, g_free);
+		trust->schema_tmp = NULL;;
 		LOG_ERROR("manager schema(): %s(%d)\n", strerror(-err), -err);
 		return KNOT_CLOUD_FAILURE;
 	}
+
+	/* If POST succeed: free old schema and use the new one */
+	g_slist_free_full(trust->schema, g_free);
+	trust->schema = trust->schema_tmp;
+	trust->schema_tmp = NULL;;

 	return KNOT_SUCCESS;
 }


usb: Add BOS Descriptors

usb: Add BOS Descriptors

Add Binary Device Object Store descriptors

Signed-off-by: Andrei Emeltchenko <a6565233ddc88e4fb9c66c1d70743223493f2ed4@intel.com>

--- include/usb/usb_common.h
+++ include/usb/usb_common.h
@@ -65,10 +65,12 @@
 #define USB_ENDPOINT_DESC		0x05
 #define USB_DEVICE_QUAL_DESC		0x06
 #define USB_INTERFACE_ASSOC_DESC	0x0B
+#define USB_DEVICE_CAPABILITY_DESC	0x10
 #define USB_HID_DESC			0x21
 #define USB_HID_REPORT_DESC		0x22
 #define USB_DFU_FUNCTIONAL_DESC		0x21
 #define USB_ASSOCIATION_DESC		0x0B
+#define USB_BINARY_OBJECT_STORE_DESC	0x0F

 /* Useful define */
 #define USB_1_1				0x0110
@@ -196,4 +198,25 @@
 	u8_t bInterval;
 } __packed;

+/** Binary Device Object Store (BOS) */
+
+#define USB_BOS_CAPABILITY_PLATFORM	0x05
+
+/** BOS Capability Descriptor */
+struct usb_bos_platform_descriptor {
+	u8_t bLength;
+	u8_t bDescriptorType;
+	u8_t bDevCapabilityType;
+	u8_t bReserved;
+	u8_t PlatformCapabilityUUID[16];
+} __packed;
+
+/** BOS Descriptor */
+struct usb_bos_descriptor {
+	u8_t bLength;
+	u8_t bDescriptorType;
+	u16_t wTotalLength;
+	u8_t bNumDeviceCaps;
+} __packed;
+
 #endif /* USB_COMMON_H_ */


fix OpenBSD warning ... icmp_data as we use it is correct and points to (casted) response buffer which holds the data (256 bytes), but the 'struct icmp' declaration uses union and reserves one byte for data start (which doesn't mean that there are no more data), so gcc produced false positive warning

--- src/net.c
+++ src/net.c
@@ -533,7 +533,8 @@
                                 if ((read_timeout = timeout * 1000. - ((t_in.tv_sec - t_out.tv_sec) * 1000. + (t_in.tv_usec - t_out.tv_usec) / 1000.)) > 0)
                                         goto readnext; // Try to read next packet, but don't exceed the timeout while waiting for our response so we won't loop forever if the socket is flooded with other ICMP packets
                         } else {
-                                memcpy(&t_out, icmpin->icmp_data, sizeof(struct timeval));
+                                data = icmpin->icmp_data;
+                                memcpy(&t_out, data, sizeof(struct timeval));
                                 response = (double)(t_in.tv_sec - t_out.tv_sec) + (double)(t_in.tv_usec - t_out.tv_usec) / 1000000;
                                 DEBUG("ICMP echo response for %s %d/%d succeeded -- received id=%d sequence=%d response_time=%fs\n", hostname, i + 1, count, id_in, seq_in, response);
                                 break; // Wait for one response only


Fix NEON intrinsic define and adding a new one for NEON on ARM64.

--- includes/acl/math/math.h
+++ includes/acl/math/math.h
@@ -48,8 +48,12 @@
 	#define ACL_SSE2_INTRINSICS
 #endif

-#if defined(__ARM_NEON)
+#if defined(__ARM_NEON) && !defined(ACL_NO_INTRINSICS)
 	#define ACL_NEON_INTRINSICS
+
+	#if defined(__aarch64__)
+		#define ACL_NEON64_INTRINSICS
+	#endif
 #endif

 #if !defined(ACL_SSE2_INTRINSICS) && !defined(ACL_NEON_INTRINSICS) && !defined(ACL_NO_INTRINSICS)


Rate limit getblocks to work around sync performance issue

See belovachap/peercoin@5d7807c of the sunnyking peercoin repo

--- src/net.h
+++ src/net.h
@@ -195,6 +195,8 @@
     uint256 hashContinue;
     CBlockIndex* pindexLastGetBlocksBegin;
     uint256 hashLastGetBlocksEnd;
+    int64 nLastGetBlocksTime;
+    int nLastGetBlocksHeight;
     int nStartingHeight;

     // flood relay
@@ -235,6 +237,8 @@
         hashContinue = 0;
         pindexLastGetBlocksBegin = 0;
         hashLastGetBlocksEnd = 0;
+        nLastGetBlocksTime = 0;
+        nLastGetBlocksHeight = -1;
         nStartingHeight = -1;
         fGetAddr = false;
         nMisbehavior = 0;


Remove a startup loop and use self-fixing

--- src/nnn.c
+++ src/nnn.c
@@ -582,6 +582,7 @@
 static inline bool getutil(char *util);
 static size_t mkpath(const char *dir, const char *name, char *out);
 static void updateselbuf(const char *path, char *newpath);
+static char *xgetenv(const char *name, char *fallback);

 /* Functions */

@@ -1140,6 +1141,7 @@
 static bool initcurses(mmask_t *oldmask)
 {
 	short i;
+	char *colors = xgetenv(env_cfg[NNN_CONTEXT_COLORS], "4444");

 	if (cfg.picker) {
 		if (!newterm(NULL, stderr, stdin)) {
@@ -1168,9 +1170,16 @@
 	start_color();
 	use_default_colors();

-	/* Initialize default colors */
-	for (i = 0; i <  CTX_MAX; ++i)
+	/* Get and set the context colors */
+	for (i = 0; i <  CTX_MAX; ++i) {
+		if (*colors) {
+			g_ctx[i].color = (*colors < '0' || *colors > '7') ? 4 : *colors - '0';
+			++colors;
+		} else
+			g_ctx[i].color = 4;
+
 		init_pair(i + 1, g_ctx[i].color, -1);
+	}

 	settimeout(); /* One second */
 	set_escdelay(25);
@@ -5640,24 +5649,6 @@
 	if (!cfg.picker && !(isatty(STDIN_FILENO) && isatty(STDOUT_FILENO)))
 		exit(1);

-	/* Get the context colors; copier used as tmp var */
-	copier = xgetenv(env_cfg[NNN_CONTEXT_COLORS], "4444");
-	opt = 0;
-	while (opt < CTX_MAX) {
-		if (*copier) {
-			if (*copier < '0' || *copier > '7') {
-				fprintf(stderr, "0 <= code <= 7\n");
-				return _FAILURE;
-			}
-
-			g_ctx[opt].color = *copier - '0';
-			++copier;
-		} else
-			g_ctx[opt].color = 4;
-
-		++opt;
-	}
-
 #ifdef DBGMODE
 	enabledbg();
 	DPRINTF_S(VERSION);


define SED only if not already defined

define SED only if not already defined

This allows packagers to set a custom path for sed (gsed may be simply
called `gsed' or `gnu-sed' or ...)

--- src/nnn.c
+++ src/nnn.c
@@ -202,11 +202,13 @@
 #define CTX_MAX 8
 #endif

+#ifndef SED
 /* BSDs or Solaris or SunOS */
 #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE__) || defined(sun) || defined(__sun)
 #define SED "gsed"
 #else
 #define SED "sed"
+#endif
 #endif

 /* Large selection threshold */


Set the corrent keybind for plugin

Set the corrent keybind for plugin

--- src/nnn.c
+++ src/nnn.c
@@ -2328,7 +2328,7 @@
 			c = getch();
 			if (c != ERR) {
 				ungetch(c);
-				c = CONTROL('S');
+				c = ';';
 			} else
 				c = 27;
 			settimeout();
@@ -2603,7 +2603,7 @@
 		case 27: /* Exit filter mode on Escape and Alt+key */
 			if (handle_alt_key(ch) != ERR) {
 				unget_wch(*ch);
-				*ch = CONTROL('S');
+				*ch = ';';
 			}
 			goto end;
 		}


Initialize mask

Initialize mask

--- src/nnn.c
+++ src/nnn.c
@@ -1209,8 +1209,7 @@
 #if NCURSES_MOUSE_VERSION <= 1
 	mousemask(BUTTON1_PRESSED | BUTTON1_DOUBLE_CLICKED, oldmask);
 #else
-	mousemask(BUTTON1_PRESSED | BUTTON4_PRESSED | BUTTON5_PRESSED,
-		  oldmask);
+	mousemask(BUTTON1_PRESSED | BUTTON4_PRESSED | BUTTON5_PRESSED, oldmask);
 #endif
 	mouseinterval(0);
 	curs_set(FALSE); /* Hide cursor */
@@ -5868,7 +5867,7 @@

 int main(int argc, char *argv[])
 {
-	mmask_t mask;
+	mmask_t mask = 0;
 	char *arg = NULL;
 	char *session = NULL;
 	int opt;


free state map before the actual states itself

--- src/nyx.c
+++ src/nyx.c
@@ -513,18 +513,18 @@
         nyx->proc = NULL;
     }

+    if (nyx->state_map)
+    {
+        hash_destroy(nyx->state_map);
+        nyx->state_map = NULL;
+    }
+
     if (nyx->states)
     {
         list_destroy(nyx->states);
         nyx->states = NULL;
     }

-    if (nyx->state_map)
-    {
-        hash_destroy(nyx->state_map);
-        nyx->state_map = NULL;
-    }
-
     if (nyx->watches)
     {
         hash_destroy(nyx->watches);


Endian swap in obj.c

Endian swap in obj.c

--- src/obj.c
+++ src/obj.c
@@ -20,17 +20,61 @@
     for (int _dummy = 0; !_dummy && (Count) > 0; _dummy++) \
         list_foreach(Tag, Name, List)

-static inline void get_sized(void *what, size_t size, size_t count, FILE *where)
+static inline void get_sized_le(void *what, size_t size, size_t count, FILE *where)
 {
     if (fread(what, size, count, where) != count)
         fatal(PRINT_ERRNO, "Unknown error in %s while parsing object", __func__);
 }

-static inline void put_sized(const void *what, size_t size, size_t count, FILE *where)
+static inline void put_sized_le(const void *what, size_t size, size_t count, FILE *where)
 {
     if (fwrite(what, size, count, where) != count)
         fatal(PRINT_ERRNO, "Unknown error in %s while emitting object", __func__);
 }
+
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+#define get_sized get_sized_le
+#define put_sized put_sized_le
+#else
+static inline UWord swapword(const UWord in)
+{
+    return (((in >> 24) & 0xff) <<  0) |
+           (((in >> 16) & 0xff) <<  8) |
+           (((in >>  8) & 0xff) << 16) |
+           (((in >>  0) & 0xff) << 24);
+}
+
+static inline void get_sized_be(void *what, size_t size, size_t count, FILE *where)
+{
+    get_sized_le(what, size, count, where);
+    // get_sized() isn't as general as it looks - it does bytes, UWords, and
+    // strings.
+    if (size == sizeof(UWord)) {
+        UWord *dest = what;
+        for (size_t i = 0; i < count; i++)
+            dest[i] = swapword(dest[i]);
+    }
+}
+
+static inline void put_sized_be(const void *what, size_t size, size_t count, FILE *where)
+{
+    // put_sized() has an analagous caveat to get_sized()'s, but we only swap
+    // one word at a time so we don't have to allocate arbitrarily-large
+    // buffers.
+    if (size == sizeof(UWord)) {
+        const UWord *src = what;
+        for (size_t i = 0; i < count; i++) {
+            const UWord temp = swapword(src[i]);
+            put_sized_le(&temp, sizeof(UWord), 1, where);
+        }
+    } else {
+        put_sized_le(what, size, count, where);
+    }
+}
+
+#define get_sized get_sized_be
+#define put_sized put_sized_be
+#endif

 static int obj_v0_write(struct obj *o, FILE *out)
 {
@@ -113,8 +157,7 @@
         rec->data = calloc(rec->size, sizeof *rec->data);
         if (!rec->data)
             fatal(PRINT_ERRNO, "Failed to allocate record data field");
-        if (fread(rec->data, sizeof *rec->data, rec->size, in) != rec->size)
-            fatal(PRINT_ERRNO, "Unknown error occurred while parsing object");
+        get_sized(rec->data, sizeof *rec->data, rec->size, in);
     }

     GET(o->sym_count, in);


obu/tile_group: simplify tile group order to check

The simplified versions catches tg_start != 0 for the first tile group
too. Fixes a heap-buffer-overflow in setup_tile when the first tile index is
larger than 0 but the number of tiles is correct. Fixes #61, #73.

--- src/obu.c
+++ src/obu.c
@@ -1046,10 +1046,9 @@
         c->tile[c->n_tile_data].data.ref = in->ref;
         c->tile[c->n_tile_data].data.data = in->data + off;
         c->tile[c->n_tile_data].data.sz = len + init_off - off;
+        // ensure tile groups are in order and sane, see 6.10.1
         if (c->tile[c->n_tile_data].start > c->tile[c->n_tile_data].end ||
-            (c->n_tile_data > 0 &&
-             (c->tile[c->n_tile_data].start !=
-              c->tile[c->n_tile_data - 1].end + 1)))
+            c->tile[c->n_tile_data].start != c->n_tiles)
         {
             for (int i = 0; i <= c->n_tile_data; i++)
                 dav1d_data_unref(&c->tile[i].data);


lib: always set operating_point_idc and max_spatial_id

This clears stale values from the context in the scenario where you first parse
a svc sequence, and then a sequence header with the reduced still picture
header flag being true immediately after it.

--- src/obu.c
+++ src/obu.c
@@ -135,16 +135,17 @@
                 op->initial_display_delay = dav1d_get_bits(gb, 4) + 1;
             }
         }
-        const int op_idx =
-            c->operating_point < hdr->num_operating_points ? c->operating_point : 0;
-        c->operating_point_idc = hdr->operating_points[op_idx].idc;
-        const unsigned spatial_mask = c->operating_point_idc >> 8;
-        c->max_spatial_id = spatial_mask ? ulog2(spatial_mask) : 0;
 #if DEBUG_SEQ_HDR
         printf("SEQHDR: post-operating-points: off=%u\n",
                dav1d_get_bits_pos(gb) - init_bit_pos);
 #endif
     }
+
+    const int op_idx =
+        c->operating_point < hdr->num_operating_points ? c->operating_point : 0;
+    c->operating_point_idc = hdr->operating_points[op_idx].idc;
+    const unsigned spatial_mask = c->operating_point_idc >> 8;
+    c->max_spatial_id = spatial_mask ? ulog2(spatial_mask) : 0;

     hdr->width_n_bits = dav1d_get_bits(gb, 4) + 1;
     hdr->height_n_bits = dav1d_get_bits(gb, 4) + 1;


Reorder the initialization (just for casual clean up)

--- src/pcm.c
+++ src/pcm.c
@@ -128,8 +128,8 @@
 	}

 	pcm->card = card;
+	pcm->stream = stream;
 	pcm->device = dev;
-	pcm->stream = stream;
 	pcm->subdevice = subdev;
 	pcm->protocol = ver;
 	pcm->fd = fd;


Make t/codingstd/c_parens.t happy.

Make t/codingstd/c_parens.t happy.

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

--- src/pdb.c
+++ src/pdb.c
@@ -219,8 +219,8 @@
     Parrot_exception exp;

     if (setjmp(exp.destination)) {
-        fprintf( stderr, "Caught exception: %s\n",
-            string_to_cstring(interp, interp->exceptions->msg) );
+        fprintf(stderr, "Caught exception: %s\n",
+            string_to_cstring(interp, interp->exceptions->msg));
         return;
     }


pki: Correctly update the ECDSA keytype.

--- src/pki.c
+++ src/pki.c
@@ -738,6 +738,9 @@
                 if (rc < 0) {
                     goto fail;
                 }
+
+                /* Update key type */
+                key->type_c = ssh_pki_key_ecdsa_name(key);
             }
             break;
 #endif
@@ -994,8 +997,12 @@
         case SSH_KEYTYPE_ECDSA:
 #ifdef HAVE_ECC
             rc = pki_key_generate_ecdsa(key, parameter);
-            if(rc == SSH_ERROR)
+            if (rc == SSH_ERROR) {
                 goto error;
+            }
+
+            /* Update key type */
+            key->type_c = ssh_pki_key_ecdsa_name(key);
             break;
 #endif
         case SSH_KEYTYPE_UNKNOWN:


Remove dot at the end of errx() message.

Noted by:	bde
MFC after:	3 days

--- tools/regression/posixsem2/semtest.c
+++ tools/regression/posixsem2/semtest.c
@@ -66,7 +66,7 @@
 		err(2, "second sem_open call failed");
 	if (s != s2)
 		errx(3,
-"two sem_open calls for same semaphore do not return same address.");
+"two sem_open calls for same semaphore do not return same address");
 	if (sem_close(s2))
 		err(4, "sem_close failed");
 	if ((pid = fork()) == 0) {


Fix wrong enum value used for VBLANK interrupt

--- src/ppu.c
+++ src/ppu.c
@@ -49,7 +49,7 @@
 				if(hblank_count == SCREEN_RES_Y)
 				{
 					gfxmode = VBLANK;
-					set_interrupt(VBLANK, true);
+					set_interrupt(INT_VBLANK, true);
 				}
 				else
 				{


Double precision pvq: using a narrower search for gain and theta

Makes the search less incredibly slow.

--- src/pvq.c
+++ src/pvq.c
@@ -383,16 +383,16 @@
   noref = 0;
   m = 0;
   s = 1;
-  if (corr > 0)
-  {
+  if (corr > 0) {
     /* Perform theta search only if prediction is useful. */
     corr = corr/(1e-100+g*gr);
     corr = OD_MAXF(OD_MINF(corr, 1.), -1.);
     theta = acos(corr);
     m = compute_householder(x, r, n, gr, &s);
     x[m] = 0;
-  /* Search for the best gain. */
-    for (i = 0; i <= ceil(cg+.5); i++) {
+    /* Search for the best gain. */
+    for (i = (int)floor(cg-gain_offset)-1; i <= (int)ceil(cg-gain_offset);
+     i++) {
       int j;
       int ts;
       qcg = i+gain_offset;
@@ -400,8 +400,8 @@
       ts = (int)floor(.5 + qcg*M_PI/2);
       if (qcg < 1.4) ts = 1;
       /* Search for the best angle. */
-      for (j = 0; j <= OD_MINI(ts-1, (int)ceil(theta*2/M_PI*ts)); j++)
-      {
+      for (j = OD_MAXI(0,(int)floor(.5+theta*2/M_PI*ts)-1);
+       j <= OD_MINI(ts-1, (int)ceil(theta*2/M_PI*ts)); j++) {
         double cos_dist;
         double dist;
         double dist_theta;
@@ -411,9 +411,11 @@
         k = floor(.5 + qcg*sin(qtheta)*sqrt(n/2));
         cos_dist = pvq_search_double(x, n, k, y);
         dist_theta = 2 - 2*cos(theta - qtheta)
-        + sin(theta)*sin(qtheta)*(2 - 2*cos_dist);
+         + sin(theta)*sin(qtheta)*(2 - 2*cos_dist);
         dist = (qcg - cg)*(qcg - cg) + qcg*cg*dist_theta;
         dist += .05*log2(n)*k;
+        if (j == 0) dist -= .1;
+        if (i == icgr) dist -= .1;
         if (dist < best_dist) {
           best_dist = dist;
           qg = i;
@@ -451,8 +453,7 @@
   qcg = qg+gain_offset;
   if (qg == 0) qcg = 0;
   k = best_k;
-  if (noref)
-  {
+  if (noref) {
     double x1[MAXN];
     for(i = 0; i < n; i++) x1[i] = x0[i];
     pvq_search_double(x1, n, k, y);


Bug fix

Bug fix

--- src/qIo.c
+++ src/qIo.c
@@ -103,12 +103,14 @@
 	ssize_t total  = 0;
 	while(total < nbytes) {
 		if(qIoWaitReadable(fd, timeoutms) <= 0) break;
+		errno = 0;
 		ssize_t rsize = read(fd, buf + total, nbytes - total);
-		if(rsize == 0) {
-			// possible with non-block socket
-			usleep(1);
-			continue;
-		} else if(rsize < 0) {
+		if(rsize <= 0) {
+			if(errno == EAGAIN || errno == EINPROGRESS) {
+				// possible with non-block io
+				usleep(1);
+				continue;
+			}
 			break;
 		}
 		total += rsize;
@@ -134,13 +136,15 @@
 	ssize_t total  = 0;
 	while(total < nbytes) {
 		if(qIoWaitWritable(fd, timeoutms) <= 0) break;
+		errno = 0;
 		ssize_t wsize = write(fd, buf + total, nbytes - total);
-		if(wsize == 0) {
-			// possible with non-block socket
-			usleep(1);
-			continue;
-		} else if(wsize < 0){
-			 break;
+		if(wsize <= 0){
+			if(errno == EAGAIN || errno == EINPROGRESS) {
+				// possible with non-block io
+				usleep(1);
+				continue;
+			}
+			break;
 		}
 		total += wsize;
 	}
@@ -213,12 +217,14 @@
 	char *ptr;
 	for (ptr = buf; readcnt < (bufsize - 1); ptr++) {
 		if(qIoWaitReadable(fd, timeoutms) <= 0) break;
+		errno = 0;
 		ssize_t rsize = read(fd, ptr, 1);
-		if(rsize == 0) {
-			// possible with non-block socket
-			usleep(1);
-			continue;
-		} else if(rsize != 1) {
+		if(rsize != 1) {
+			if(errno == EAGAIN || errno == EINPROGRESS) {
+				// possible with non-block io
+				usleep(1);
+				continue;
+			}
 			break;
 		}


一応シンボルが長すぎた場合のエラー処理を追加

一応シンボルが長すぎた場合のエラー処理を追加

--- pureLisp.c
+++ pureLisp.c
@@ -1,4 +1,6 @@
 #include <stdio.h>
+#include <stdlib.h>
+#include "pureLisp.h"

 // Xy[XȊO̕񂪗܂œ͂̂Ă
 void skipSpace(FILE *fp) {
@@ -48,6 +50,11 @@
 		}
 		buf[ptr++] = c;
 		c = fgetc(fp);
+		if (ptr >= MAX_TOKEN_LENGTH) {
+			buf[MAX_TOKEN_LENGTH -1] = '\0';
+			printf("token %s is too long.", buf);
+			exit(1);
+		}
 	}
 	buf[ptr++] = '\0';
 	ungetc(c, fp);


Fix comments in function raxLowWalk of listpack.c

--- src/rax.c
+++ src/rax.c
@@ -487,8 +487,8 @@
         if (h->iscompr) j = 0; /* Compressed node only child is at index 0. */
         memcpy(&h,children+j,sizeof(h));
         parentlink = children+j;
-        j = 0; /* If the new node is compressed and we do not
-                  iterate again (since i == l) set the split
+        j = 0; /* If the new node is non compressed and we do not
+                  iterate again (since i == len) set the split
                   position to 0 to signal this node represents
                   the searched key. */
     }


Use new slave name function for diskless repl reporting.

--- src/rdb.c
+++ src/rdb.c
@@ -1347,15 +1347,15 @@
             }
             if (j == ok_slaves[0] || errorcode != 0) {
                 redisLog(REDIS_WARNING,
-                "Closing slave %llu: child->slave RDB transfer failed: %s",
-                    slave->id,
+                "Closing slave %s: child->slave RDB transfer failed: %s",
+                    replicationGetSlaveName(slave),
                     (errorcode == 0) ? "RDB transfer child aborted"
                                      : strerror(errorcode));
                 freeClient(slave);
             } else {
                 redisLog(REDIS_WARNING,
-                "Slave %llu correctly received the streamed RDB file.",
-                slave->id);
+                "Slave %s correctly received the streamed RDB file.",
+                    replicationGetSlaveName(slave));
                 /* Restore the socket as non-blocking. */
                 anetNonBlock(NULL,slave->fd);
                 anetSendTimeout(NULL,slave->fd,0);


rdbLoad() should check REDIS_RDB_VERSION instead of hardcoded number.

--- src/rdb.c
+++ src/rdb.c
@@ -1039,7 +1039,7 @@
         return REDIS_ERR;
     }
     rdbver = atoi(buf+5);
-    if (rdbver < 1 || rdbver > 5) {
+    if (rdbver < 1 || rdbver > REDIS_RDB_VERSION) {
         fclose(fp);
         redisLog(REDIS_WARNING,"Can't handle RDB format version %d",rdbver);
         errno = EINVAL;


RDB压缩

RDB压缩

--- src/rdb.h
+++ src/rdb.h
@@ -38,6 +38,7 @@

 /* The current RDB version. When the format changes in a way that is no longer
  * backward compatible this number gets incremented. */
+/* 当前版本的RDB已经不向后兼容了 */
 #define RDB_VERSION 7

 /* Defines related to the dump file format. To store 32 bits lengths for short
@@ -53,6 +54,7 @@
  *
  * Lengths up to 63 are stored using a single byte, most DB keys, and may
  * values, will fit inside. */
+/* 大数的压缩 */
 #define RDB_6BITLEN 0
 #define RDB_14BITLEN 1
 #define RDB_32BITLEN 2


more strict check in rioConnRead (#7564)

--- src/rio.c
+++ src/rio.c
@@ -201,7 +201,7 @@
             /* Make sure the caller didn't request to read past the limit.
              * If they didn't we'll buffer till the limit, if they did, we'll
              * return an error. */
-            if (r->io.conn.read_limit >= r->io.conn.read_so_far + needs)
+            if (r->io.conn.read_limit >= r->io.conn.read_so_far + len)
                 toread = r->io.conn.read_limit - r->io.conn.read_so_far - buffered;
             else {
                 errno = EOVERFLOW;


epollified server socket connection acceptance

--- src/rsp.c
+++ src/rsp.c
@@ -7,7 +7,10 @@
 #include <netdb.h>
 #include <unistd.h>
 #include <fcntl.h>
-
+#include <errno.h>
+#include <sys/epoll.h>
+
+#define MAX_EPOLL_EVENTS 10
 #define MAX_LISTEN_BACKLOG 1
 #define BUFFER_SIZE 4096

@@ -151,8 +154,13 @@
     char *backend_addr;
     char *backend_port_str;

+    int epoll_fd;
     int server_socket_fd;
     int client_socket_fd;
+
+    struct epoll_event epoll_events[MAX_EPOLL_EVENTS];
+    struct epoll_event server_socket_event;
+

     if (argc != 4) {
         fprintf(stderr,
@@ -165,20 +173,47 @@
     backend_port_str = argv[3];

     server_socket_fd = create_and_bind(server_port_str);
-    // make_socket_non_blocking(server_socket_fd);
+    make_socket_non_blocking(server_socket_fd);

     listen(server_socket_fd, MAX_LISTEN_BACKLOG);
     printf("Started.  Listening on port %s.\n", server_port_str);

+    epoll_fd = epoll_create1(0);
+    if (epoll_fd == -1) {
+        perror("Couldn't create epoll FD");
+        exit(1);
+    }
+
+    server_socket_event.data.fd = server_socket_fd;
+    server_socket_event.events = EPOLLIN | EPOLLET;
+    if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, server_socket_fd, &server_socket_event) == -1) {
+        perror("Couldn't register server socket with epoll");
+        exit(-1);
+    }
+
     while (1) {
-        client_socket_fd = accept(server_socket_fd, NULL, NULL);
-        if (client_socket_fd == -1) {
-            perror("Could not accept");
-            exit(1);
-        }
-
-        handle_client_connection(client_socket_fd, backend_addr, backend_port_str);
-    }
-
-}
-
+        int ii;
+        int num_events;
+
+        num_events = epoll_wait(epoll_fd, epoll_events, MAX_EPOLL_EVENTS, -1);
+        for (ii=0; ii < num_events; ii++ ) {
+            while (1) {
+                client_socket_fd = accept(server_socket_fd, NULL, NULL);
+                if (client_socket_fd == -1) {
+                    if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
+                        break;
+                    } else {
+                        perror("Could not accept");
+                        exit(1);
+                    }
+                }
+
+                handle_client_connection(client_socket_fd, backend_addr, backend_port_str);
+            }
+        }
+
+
+    }
+
+}
+


fix unbounded cert

fix unbounded cert

--- src/scs.c
+++ src/scs.c
@@ -630,10 +630,11 @@
     scs_printf("hit max_iters, returning best iterate\n");
   }
   scs_printf("\nstatus:  %s\n", info->status);
-  scs_printf("timings: total: %1.2es\n", info->solve_time / 1e3);
-  scs_printf("\t setup: %1.2es, lin-sys: %1.2es\n", info->setup_time / 1e3,
-             total_lin_sys_time / 1e3);
-  scs_printf("\t cones: %1.2es, accel: %1.2es\n", total_cone_time / 1e3,
+  scs_printf("timings: total: %1.2es, setup: %1.2es, solve: %1.2es\n",
+             (info->setup_time + info->solve_time) / 1e3,
+             info->setup_time / 1e3, info->solve_time / 1e3);
+  scs_printf("\t lin-sys: %1.2es, cones: %1.2es, accel: %1.2es\n",
+             total_lin_sys_time / 1e3, total_cone_time / 1e3,
              total_accel_time / 1e3);
   scs_printf("%s", lin_sys_str);
   scs_free(lin_sys_str);


minor reordering of operations

minor reordering of operations

--- src/scs.c
+++ src/scs.c
@@ -317,7 +317,7 @@

 /* compute the [r;s;kappa] iterate */
 /* rsk = u^{k+1} + v^k - 2 u_t^{k+1} */
-/* since it depends on v^k MUST be called before update_dual_vars */
+/* since it depends on v^k MUST be called before update_dual_vars is done */
 /* effect of w->stgs->alpha is cancelled out */
 static void compute_rsk(ScsWork *w) {
   scs_int i, l = w->n + w->m + 1;
@@ -329,6 +329,8 @@
 static void update_dual_vars(ScsWork *w) {
   scs_int i, n = w->n, l = n + w->m + 1;
   scs_float a = w->stgs->alpha;
+  /* compute and store [r;s;kappa] */
+  compute_rsk(w);
   /* don't relax x variable */
   for (i = 0; i < n; ++i) {
     w->v[i] += w->u[i] - w->u_t[i];
@@ -905,18 +907,8 @@
   if (w->stgs->verbose) {
     print_header(w, k);
   }
-  /* scs: */
+  /* SCS */
   for (i = 0; i < w->stgs->max_iters; ++i) {
-    /* accelerate here so that last step always projection onto cone */
-    /* this ensures the returned iterates always satisfy conic constraints */
-    SCS(tic)(&accel_timer);
-    if (i > 0 && aa_apply(w->v, w->v_prev, w->accel) != 0) {
-      /*
-      return failure(w, w->m, w->n, sol, info, SCS_FAILED,
-          "error in accelerate", "Failure");
-      */
-    }
-    total_accel_time += SCS(tocq)(&accel_timer);

     /* scs is homogeneous so scale the iterates to keep norm reasonable */
     total_norm = SQRTF(SCS(norm_sq)(w->u, l) + SCS(norm_sq)(w->v, l));
@@ -936,13 +928,13 @@
                      "error in project_cones", "Failure");
     }

-    compute_rsk(w);
     update_dual_vars(w);

     if (scs_is_interrupted()) {
       return failure(w, w->m, w->n, sol, info, SCS_SIGINT, "Interrupted",
                      "Interrupted");
     }
+
     if (i % CONVERGED_INTERVAL == 0 || iterate_norm_diff(w) < 1e-10) {
       calc_residuals(w, &r, i);
       if ((info->status_val = has_converged(w, &r, i)) != 0) {
@@ -956,7 +948,18 @@
       update_best_iterate(w, &r);
       print_summary(w, i, &r, &solve_timer);
     }
-  }
+
+    /* Finally apply any acceleration */
+    SCS(tic)(&accel_timer);
+    if (aa_apply(w->v, w->v_prev, w->accel) != 0) {
+      /*
+      return failure(w, w->m, w->n, sol, info, SCS_FAILED,
+          "error in accelerate", "Failure");
+      */
+    }
+    total_accel_time += SCS(tocq)(&accel_timer);
+  }
+
   if (w->stgs->verbose) {
     calc_residuals(w, &r, i);
     print_summary(w, i, &r, &solve_timer);
@@ -968,6 +971,7 @@
   if (w->stgs->verbose) {
     print_footer(d, k, sol, w, info, total_accel_time);
   }
+
   scs_end_interrupt_listener();
   return info->status_val;
 }


sdscatvprintf(): guess buflen using format length.

sdscatvprintf() uses a loop where it tries to output the formatted
string in a buffer of the initial length, if there was not enough room,
a buffer of doubled size is tried and so forth.

The initial guess for the buffer length was very poor, an hardcoded
"16". This caused the printf to be processed multiple times without a
good reason. Given that printf functions are already not fast, the
overhead was significant.

The new heuristic is to use a buffer 4 times the length of the format
buffer, and 32 as minimal size. This appears to be a good balance for
typical uses of the function inside the Redis code base.

This change improved INFO command performances 3 times.

--- src/sds.c
+++ src/sds.c
@@ -293,8 +293,9 @@
 sds sdscatvprintf(sds s, const char *fmt, va_list ap) {
     va_list cpy;
     char *buf, *t;
-    size_t buflen = 16;
-
+    size_t buflen = strlen(fmt)*4;
+
+    if (buflen < 32) buflen = 32;
     while(1) {
         buf = zmalloc(buflen);
         if (buf == NULL) return NULL;


Redis字符串操作

Redis字符串操作

--- src/sds.c
+++ src/sds.c
@@ -184,6 +184,7 @@
  * However all the existing buffer is not discarded but set as free space
  * so that next append operations will not require allocations up to the
  * number of bytes previously available. */
+/*字符串删除*/
 void sdsclear(sds s) {
     sdssetlen(s, 0);
     s[0] = '\0';
@@ -246,6 +247,7 @@
  *
  * After the call, the passed sds string is no longer valid and all the
  * references must be substituted with the new pointer returned by the call. */
+/* 删除字符串末尾空空格 */
 sds sdsRemoveFreeSpace(sds s) {
     void *sh, *newsh;
     char type, oldtype = s[-1] & SDS_TYPE_MASK;
@@ -359,6 +361,7 @@
  *
  * if the specified length is smaller than the current length, no operation
  * is performed. */
+/* 张家字符串长度， 并设置为0 */
 sds sdsgrowzero(sds s, size_t len) {
     size_t curlen = sdslen(s);

@@ -377,6 +380,7 @@
  *
  * After the call, the passed sds string is no longer valid and all the
  * references must be substituted with the new pointer returned by the call. */
+/* 按长度给字符串添加其他子字符串 */
 sds sdscatlen(sds s, const void *t, size_t len) {
     size_t curlen = sdslen(s);

@@ -392,6 +396,7 @@
  *
  * After the call, the passed sds string is no longer valid and all the
  * references must be substituted with the new pointer returned by the call. */
+/* 追加字符串 */
 sds sdscat(sds s, const char *t) {
     return sdscatlen(s, t, strlen(t));
 }
@@ -400,12 +405,14 @@
  *
  * After the call, the modified sds string is no longer valid and all the
  * references must be substituted with the new pointer returned by the call. */
+/* 追加字符串 */
 sds sdscatsds(sds s, const sds t) {
     return sdscatlen(s, t, sdslen(t));
 }

 /* Destructively modify the sds string 's' to hold the specified binary
  * safe string pointed by 't' of length 'len' bytes. */
+/* 按长度拷贝字符串 */
 sds sdscpylen(sds s, const char *t, size_t len) {
     if (sdsalloc(s) < len) {
         s = sdsMakeRoomFor(s,len-sdslen(s));
@@ -419,6 +426,7 @@

 /* Like sdscpylen() but 't' must be a null-termined string so that the length
  * of the string is obtained with strlen(). */
+/* 拷贝字符串到s */
 sds sdscpy(sds s, const char *t) {
     return sdscpylen(s, t, strlen(t));
 }


fix failed assertion during smf_delete().  add install target.

git-svn-id: 87740cf925d2af6507580ca896643f01d639dae1@324 bede6af4-a197-dd11-9785-00d0b7b2942b

--- src/smf.c
+++ src/smf.c
@@ -92,12 +92,12 @@
 	assert(track);
 	assert(track->events_array);

-	if (track->smf)
-		smf_remove_track(track);
-
 	/* Remove all the events, from last to first. */
 	while (track->events_array->len > 0)
 		smf_event_delete(g_ptr_array_index(track->events_array, track->events_array->len - 1));
+
+	if (track->smf)
+		smf_remove_track(track);

 	assert(track->events_array->len == 0);
 	assert(track->number_of_events == 0);