Skip to content

Commit

Permalink
Resolve merge conflict on docs/index.md
Browse files Browse the repository at this point in the history
  • Loading branch information
TerryE committed Apr 4, 2019
2 parents 1159295 + 3f5ae99 commit 4905381
Show file tree
Hide file tree
Showing 545 changed files with 43,195 additions and 54,483 deletions.
14 changes: 7 additions & 7 deletions .gdbinit
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#
# This is very much a work in progress to show how we can use macros to make the
# GDB interface a lot more useable. For example the next / step commands only
# work if the stepper doesn't leave the current scope. Beyond that you have a
# single hardware breakpoint which can be used as an hb or a wa. You have to
# remember to delete the previous one, so the br macro does this for you.
# This is very much a work in progress to show how we can use macros to make the
# GDB interface a lot more useable. For example the next / step commands only
# work if the stepper doesn't leave the current scope. Beyond that you have a
# single hardware breakpoint which can be used as an hb or a wa. You have to
# remember to delete the previous one, so the br macro does this for you.
#
file app/.output/eagle/debug/image/eagle.app.v6.out
#set remotedebug 1
Expand All @@ -16,12 +16,12 @@ target remote /dev/ttyUSB0

set confirm off
set print null-stop
define br
define br
d
hb $arg0
end

define upto
define upto
d
hb $arg0
c
Expand Down
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Provide a [Minimal, Complete, and Verifiable example](http://stackoverflow.com/h
Which branch are you on? If you know the Git revision then add it here as well.

### Hardware
Describe which ESP8266 device you use and document any special hardware setup
Describe which ESP8266 device you use and document any special hardware setup
required to reproduce the problem.

8<------------------------ END BUG REPORT -------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ Make sure all boxes are checked (add x inside the brackets) when you submit your
- [ ] This PR is for the `dev` branch rather than for `master`.
- [ ] This PR is compliant with the [other contributing guidelines](https://github.com/nodemcu/nodemcu-firmware/blob/dev/CONTRIBUTING.md) as well (if not, please describe why).
- [ ] I have thoroughly tested my contribution.
- [ ] The code changes are reflected in the documentation at `docs/en/*`.
- [ ] The code changes are reflected in the documentation at `docs/*`.

\<Description of and rationale behind this PR\>
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ Avoid intermediate merge commits. [Rebase](https://www.atlassian.com/git/tutoria

This is just one way of doing things. If you're proficient in Git matters you're free to choose your own. If you want to read more then the [GitHub chapter in the Git book](http://git-scm.com/book/en/v2/GitHub-Contributing-to-a-Project#The-GitHub-Flow) is a way to start. [GitHub's own documentation](https://help.github.com/categories/collaborating-with-issues-and-pull-requests/) contains a wealth of information as well.

As a Windows or Mac user you could also resort to [GitHub Desktop](https://desktop.github.com/). It's a mature GUI application that supports most of the tasks outlined above.
As a Windows or Mac user you could also resort to [GitHub Desktop](https://desktop.github.com/). It's a mature GUI application that supports most of the tasks outlined above.

### Keeping your fork in sync
You need to sync your fork with the NodeMCU upstream repository from time to time, latest before you rebase (see flow above).
Expand Down
51 changes: 45 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,25 @@ else
CCFLAGS += -O2
endif

#Handling of V=1/VERBOSE=1 flag
#
# if V=1, $(summary) does nothing
# if V is unset or not 1, $(summary) echoes a summary
VERBOSE ?=
V ?= $(VERBOSE)
ifeq ("$(V)","1")
export summary := @true
else
export summary := @echo

# disable echoing of commands, directory names
MAKEFLAGS += --silent -w
endif # $(V)==1

ifndef BAUDRATE
BAUDRATE=115200
endif

#############################################################
# Select compile
#
Expand Down Expand Up @@ -186,6 +205,7 @@ $$(LIBODIR)/$(1).a: $$(OBJS) $$(DEP_OBJS_$(1)) $$(DEP_LIBS_$(1)) $$(DEPENDS_$(1)
@mkdir -p $$(LIBODIR)
$$(if $$(filter %.a,$$?),mkdir -p $$(EXTRACT_DIR)_$(1))
$$(if $$(filter %.a,$$?),cd $$(EXTRACT_DIR)_$(1); $$(foreach lib,$$(filter %.a,$$?),$$(AR) xo $$(UP_EXTRACT_DIR)/$$(lib);))
$(summary) AR $(patsubst $(TOP_DIR)/%,%,$(CURDIR))/$<
$$(AR) ru $$@ $$(filter %.o,$$?) $$(if $$(filter %.a,$$?),$$(EXTRACT_DIR)_$(1)/*.o)
$$(if $$(filter %.a,$$?),$$(RM) -r $$(EXTRACT_DIR)_$(1))
endef
Expand All @@ -195,12 +215,15 @@ DEP_LIBS_$(1) = $$(foreach lib,$$(filter %.a,$$(COMPONENTS_$(1))),$$(dir $$(lib)
DEP_OBJS_$(1) = $$(foreach obj,$$(filter %.o,$$(COMPONENTS_$(1))),$$(dir $$(obj))$$(OBJODIR)/$$(notdir $$(obj)))
$$(IMAGEODIR)/$(1).out: $$(OBJS) $$(DEP_OBJS_$(1)) $$(DEP_LIBS_$(1)) $$(DEPENDS_$(1))
@mkdir -p $$(IMAGEODIR)
$(summary) LD $(patsubst $(TOP_DIR)/%,%,$(CURDIR))/$$@
$$(CC) $$(LDFLAGS) $$(if $$(LINKFLAGS_$(1)),$$(LINKFLAGS_$(1)),$$(LINKFLAGS_DEFAULT) $$(OBJS) $$(DEP_OBJS_$(1)) $$(DEP_LIBS_$(1))) -o $$@
endef

$(BINODIR)/%.bin: $(IMAGEODIR)/%.out
@mkdir -p $(BINODIR)
$(summary) NM $(patsubst $(TOP_DIR)/%,%,$(CURDIR))/$@
@$(NM) $< | grep -w U && { echo "Firmware has undefined (but unused) symbols!"; exit 1; } || true
$(summary) ESPTOOL $(patsubst $(TOP_DIR)/%,%,$(CURDIR))/$< $(FIRMWAREDIR)
$(ESPTOOL) elf2image --flash_mode dio --flash_freq 40m $< -o $(FIRMWAREDIR)

#############################################################
Expand All @@ -226,38 +249,45 @@ toolchain: $(TOP_DIR)/tools/toolchains/esp8266-$(PLATFORM)-$(TOOLCHAIN_VERSION)/

$(TOP_DIR)/tools/toolchains/esp8266-$(PLATFORM)-$(TOOLCHAIN_VERSION)/bin/xtensa-lx106-elf-gcc: $(TOP_DIR)/cache/toolchain-esp8266-$(PLATFORM)-$(TOOLCHAIN_VERSION).tar.xz
mkdir -p $(TOP_DIR)/tools/toolchains/
$(summary) EXTRACT $(patsubst $(TOP_DIR)/%,%,$<)
tar -xJf $< -C $(TOP_DIR)/tools/toolchains/
touch $@

$(TOP_DIR)/cache/toolchain-esp8266-$(PLATFORM)-$(TOOLCHAIN_VERSION).tar.xz:
mkdir -p $(TOP_DIR)/cache
$(summary) WGET $(patsubst $(TOP_DIR)/%,%,$@)
wget --tries=10 --timeout=15 --waitretry=30 --read-timeout=20 --retry-connrefused https://github.com/jmattsson/esp-toolchains/releases/download/$(PLATFORM)-$(TOOLCHAIN_VERSION)/toolchain-esp8266-$(PLATFORM)-$(TOOLCHAIN_VERSION).tar.xz -O $@ || { rm -f "$@"; exit 1; }
endif

$(TOP_DIR)/sdk/.extracted-$(SDK_BASE_VER): $(TOP_DIR)/cache/v$(SDK_FILE_VER).zip
mkdir -p "$(dir $@)"
$(summary) UNZIP $(patsubst $(TOP_DIR)/%,%,$<)
(cd "$(dir $@)" && rm -fr esp_iot_sdk_v$(SDK_VER) ESP8266_NONOS_SDK-$(SDK_BASE_VER) && unzip $(TOP_DIR)/cache/v$(SDK_FILE_VER).zip ESP8266_NONOS_SDK-$(SDK_BASE_VER)/lib/* ESP8266_NONOS_SDK-$(SDK_BASE_VER)/ld/eagle.rom.addr.v6.ld ESP8266_NONOS_SDK-$(SDK_BASE_VER)/include/* ESP8266_NONOS_SDK-$(SDK_BASE_VER)/bin/esp_init_data_default_v05.bin)
mv $(dir $@)/ESP8266_NONOS_SDK-$(SDK_BASE_VER) $(dir $@)/esp_iot_sdk_v$(SDK_BASE_VER)
touch $@

$(TOP_DIR)/sdk/.patched-$(SDK_VER): $(TOP_DIR)/cache/$(SDK_PATCH_VER).patch
mv $(dir $@)/esp_iot_sdk_v$(SDK_BASE_VER) $(dir $@)/esp_iot_sdk_v$(SDK_VER)
$(summary) APPLY $(patsubst $(TOP_DIR)/%,%,$<)
git apply --verbose -p1 --exclude='*VERSION' --exclude='*bin/at*' --directory=$(SDK_REL_DIR) $<
touch $@

$(TOP_DIR)/sdk/.pruned-$(SDK_VER):
rm -f $(SDK_DIR)/lib/liblwip.a $(SDK_DIR)/lib/libssl.a $(SDK_DIR)/lib/libmbedtls.a
$(summary) PRUNE libmain.a libc.a
$(AR) d $(SDK_DIR)/lib/libmain.a time.o
$(AR) d $(SDK_DIR)/lib/libc.a lib_a-time.o
touch $@

$(TOP_DIR)/cache/v$(SDK_FILE_VER).zip:
mkdir -p "$(dir $@)"
$(summary) WGET $(patsubst $(TOP_DIR)/%,%,$@)
wget --tries=10 --timeout=15 --waitretry=30 --read-timeout=20 --retry-connrefused https://github.com/espressif/ESP8266_NONOS_SDK/archive/v$(SDK_FILE_VER).zip -O $@ || { rm -f "$@"; exit 1; }
(echo "$(SDK_FILE_SHA1) $@" | sha1sum -c -) || { rm -f "$@"; exit 1; }

$(TOP_DIR)/cache/$(SDK_PATCH_VER).patch:
mkdir -p "$(dir $@)"
$(summary) WGET $(SDK_PATCH_VER).patch
wget --tries=10 --timeout=15 --waitretry=30 --read-timeout=20 --retry-connrefused "https://github.com/espressif/ESP8266_NONOS_SDK/compare/v$(SDK_BASE_VER)...$(SDK_PATCH_VER).patch" -O $@ || { rm -f "$@"; exit 1; }
(echo "$(SDK_PATCH_SHA1) $@" | sha1sum -c -) || { rm -f "$@"; exit 1; }

Expand All @@ -272,20 +302,25 @@ clobber: $(SPECIAL_CLOBBER)

flash:
@echo "use one of the following targets to flash the firmware"
@echo " make flash512k - for ESP with 512kB flash size"
@echo " make flash4m - for ESP with 4MB flash size"
@echo " make flash512k - for ESP with 512kB flash size"
@echo " make flash1m-dout - for ESP with 1MB flash size and flash mode = dout (Sonoff, ESP8285)"
@echo " make flash4m - for ESP with 4MB flash size"

flash512k:
$(MAKE) -e FLASHOPTIONS="-fm qio -fs 4m -ff 40m" flashinternal

flash4m:
$(MAKE) -e FLASHOPTIONS="-fm dio -fs 32m -ff 40m" flashinternal

flash1m-dout:
$(MAKE) -e FLASHOPTIONS="-fm dout -fs 8m -ff 40m" flashinternal


flashinternal:
ifndef PDIR
$(MAKE) -C ./app flashinternal
else
$(ESPTOOL) --port $(ESPPORT) write_flash $(FLASHOPTIONS) 0x00000 $(FIRMWAREDIR)0x00000.bin 0x10000 $(FIRMWAREDIR)0x10000.bin
$(ESPTOOL) --port $(ESPPORT) --baud $(BAUDRATE) write_flash $(FLASHOPTIONS) 0x00000 $(FIRMWAREDIR)0x00000.bin 0x10000 $(FIRMWAREDIR)0x10000.bin
endif

.subdirs:
Expand Down Expand Up @@ -318,6 +353,7 @@ ifneq ($(wildcard $(TOP_DIR)/server-ca.crt),)
pre_build: $(TOP_DIR)/app/modules/server-ca.crt.h

$(TOP_DIR)/app/modules/server-ca.crt.h: $(TOP_DIR)/server-ca.crt
$(summary) MKCERT $(patsubst $(TOP_DIR)/%,%,$<)
python $(TOP_DIR)/tools/make_server_cert.py $(TOP_DIR)/server-ca.crt > $(TOP_DIR)/app/modules/server-ca.crt.h

DEFINES += -DHAVE_SSL_SERVER_CRT=\"server-ca.crt.h\"
Expand All @@ -326,32 +362,34 @@ pre_build:
@-rm -f $(TOP_DIR)/app/modules/server-ca.crt.h
endif


$(OBJODIR)/%.o: %.c
@mkdir -p $(dir $@);
$(summary) CC $(patsubst $(TOP_DIR)/%,%,$(CURDIR))/$<
$(CC) $(if $(findstring $<,$(DSRCS)),$(DFLAGS),$(CFLAGS)) $(COPTS_$(*F)) -o $@ -c $<

$(OBJODIR)/%.d: %.c
@mkdir -p $(dir $@);
@echo DEPEND: $(CC) -M $(CFLAGS) $<
$(summary) DEPEND: CC $(patsubst $(TOP_DIR)/%,%,$(CURDIR))/$<
@set -e; rm -f $@; \
$(CC) -M $(CFLAGS) $< > $@.$$$$; \
sed 's,\($*\.o\)[ :]*,$(OBJODIR)/\1 $@ : ,g' < $@.$$$$ > $@; \
rm -f $@.$$$$

$(OBJODIR)/%.o: %.cpp
@mkdir -p $(OBJODIR);
$(summary) CXX $(patsubst $(TOP_DIR)/%,%,$(CURDIR))/$<
$(CXX) $(if $(findstring $<,$(DSRCS)),$(DFLAGS),$(CFLAGS)) $(COPTS_$(*F)) -o $@ -c $<

$(OBJODIR)/%.d: %.cpp
@mkdir -p $(OBJODIR);
@echo DEPEND: $(CXX) -M $(CFLAGS) $<
$(summary) DEPEND: CXX $(patsubst $(TOP_DIR)/%,%,$(CURDIR))/$<
@set -e; rm -f $@; \
sed 's,\($*\.o\)[ :]*,$(OBJODIR)/\1 $@ : ,g' < $@.$$$$ > $@; \
rm -f $@.$$$$

$(OBJODIR)/%.o: %.s
@mkdir -p $(dir $@);
$(summary) CC $(patsubst $(TOP_DIR)/%,%,$(CURDIR))/$<
$(CC) $(CFLAGS) -o $@ -c $<

$(OBJODIR)/%.d: %.s
Expand All @@ -363,6 +401,7 @@ $(OBJODIR)/%.d: %.s

$(OBJODIR)/%.o: %.S
@mkdir -p $(dir $@);
$(summary) CC $(patsubst $(TOP_DIR)/%,%,$(CURDIR))/$<
$(CC) $(CFLAGS) -D__ASSEMBLER__ -o $@ -c $<

$(OBJODIR)/%.d: %.S
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ wifi.sta.config{ssid="SSID", pwd="password"}

# Documentation

The entire [NodeMCU documentation](https://nodemcu.readthedocs.io) is maintained right in this repository at [/docs](docs). The fact that the API documentation is maintained in the same repository as the code that *provides* the API ensures consistency between the two. With every commit the documentation is rebuilt by Read the Docs and thus transformed from terse Markdown into a nicely browsable HTML site at [https://nodemcu.readthedocs.io](https://nodemcu.readthedocs.io).
The entire [NodeMCU documentation](https://nodemcu.readthedocs.io) is maintained right in this repository at [/docs](docs). The fact that the API documentation is maintained in the same repository as the code that *provides* the API ensures consistency between the two. With every commit the documentation is rebuilt by Read the Docs and thus transformed from terse Markdown into a nicely browsable HTML site at [https://nodemcu.readthedocs.io](https://nodemcu.readthedocs.io).

- How to [build the firmware](https://nodemcu.readthedocs.io/en/master/en/build/)
- How to [flash the firmware](https://nodemcu.readthedocs.io/en/master/en/flash/)
Expand Down
2 changes: 1 addition & 1 deletion app/coap/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ endif
# makefile at its root level - these are then overridden
# for a subtree within the makefile rooted therein
#
#DEFINES +=
#DEFINES +=

#############################################################
# Recursion Magic - Don't touch this!!
Expand Down
16 changes: 8 additions & 8 deletions app/coap/coap.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ typedef struct
uint8_t ver; /* CoAP version number */
uint8_t t; /* CoAP Message Type */
uint8_t tkl; /* Token length: indicates length of the Token field */
uint8_t code; /* CoAP status code. Can be request (0.xx), success reponse (2.xx),
* client error response (4.xx), or rever error response (5.xx)
uint8_t code; /* CoAP status code. Can be request (0.xx), success reponse (2.xx),
* client error response (4.xx), or rever error response (5.xx)
* For possible values, see http://tools.ietf.org/html/rfc7252#section-12.1 */
uint8_t id[2];
} coap_header_t;
Expand Down Expand Up @@ -164,14 +164,14 @@ struct coap_luser_entry{

struct coap_endpoint_t{
coap_method_t method; /* (i.e. POST, PUT or GET) */
coap_endpoint_func handler; /* callback function which handles this
* type of endpoint (and calls
coap_endpoint_func handler; /* callback function which handles this
* type of endpoint (and calls
* coap_make_response() at some point) */
const coap_endpoint_path_t *path; /* path towards a resource (i.e. foo/bar/) */
const coap_endpoint_path_t *path; /* path towards a resource (i.e. foo/bar/) */
const char *core_attr; /* the 'ct' attribute, as defined in RFC7252, section 7.2.1.:
* "The Content-Format code "ct" attribute
* provides a hint about the
* Content-Formats this resource returns."
* "The Content-Format code "ct" attribute
* provides a hint about the
* Content-Formats this resource returns."
* (Section 12.3. lists possible ct values.) */
coap_luser_entry *user_entry;
};
Expand Down
2 changes: 1 addition & 1 deletion app/coap/coap_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ coap_tid_t coap_send_confirmed(struct espconn *pesp_conn, coap_pdu_t *pdu) {
*/
coap_timer_stop();
coap_timer_update(&gQueue);
node->t = node->timeout;
node->t = node->timeout;
coap_insert_node(&gQueue, node);
coap_timer_start(&gQueue);
return node->id;
Expand Down
2 changes: 1 addition & 1 deletion app/coap/coap_io.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ extern "C" {
#include "espconn.h"
#include "pdu.h"
#include "hash.h"

coap_tid_t coap_send(struct espconn *pesp_conn, coap_pdu_t *pdu);

coap_tid_t coap_send_confirmed(struct espconn *pesp_conn, coap_pdu_t *pdu);
Expand Down
4 changes: 2 additions & 2 deletions app/coap/coap_timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@ void coap_timer_tick(void *arg){
node->retransmit_cnt++;
node->t = node->timeout << node->retransmit_cnt;

NODE_DBG("** retransmission #%d of transaction %d\n",
NODE_DBG("** retransmission #%d of transaction %d\n",
node->retransmit_cnt, (((uint16_t)(node->pdu->pkt->hdr.id[0]))<<8)+node->pdu->pkt->hdr.id[1]);
node->id = coap_send(node->pconn, node->pdu);
if (COAP_INVALID_TID == node->id) {
NODE_DBG("retransmission: error sending pdu\n");
coap_delete_node(node);
} else {
coap_insert_node(queue, node);
coap_insert_node(queue, node);
}
} else {
/* And finally delete the node */
Expand Down
10 changes: 5 additions & 5 deletions app/coap/endpoints.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ static int handle_post_function(const coap_endpoint_t *ep, coap_rw_buffer_t *scr
NODE_DBG("\n");
lua_settop(L, n);
return coap_make_response(scratch, outpkt, ret, len, id_hi, id_lo, &inpkt->tok, COAP_RSPCODE_CONTENT, COAP_CONTENTTYPE_TEXT_PLAIN);
}
}
} else {
lua_settop(L, n);
return coap_make_response(scratch, outpkt, NULL, 0, id_hi, id_lo, &inpkt->tok, COAP_RSPCODE_CONTENT, COAP_CONTENTTYPE_TEXT_PLAIN);
Expand All @@ -157,7 +157,7 @@ static int handle_post_function(const coap_endpoint_t *ep, coap_rw_buffer_t *scr
goto end;
}
}
NODE_DBG("none match.\n");
NODE_DBG("none match.\n");
end:
return coap_make_response(scratch, outpkt, NULL, 0, id_hi, id_lo, &inpkt->tok, COAP_RSPCODE_NOT_FOUND, COAP_CONTENTTYPE_NONE);
}
Expand Down Expand Up @@ -226,7 +226,7 @@ void build_well_known_rsp(char *rsp, uint16_t rsplen)
c_strncat(rsp, ",", len);
len--;
}

c_strncat(rsp, "<", len);
len--;

Expand All @@ -250,7 +250,7 @@ void build_well_known_rsp(char *rsp, uint16_t rsplen)
c_strncat(rsp, ",", len);
len--;
}

c_strncat(rsp, "<", len);
len--;

Expand All @@ -272,7 +272,7 @@ void build_well_known_rsp(char *rsp, uint16_t rsplen)
len -= 2;

c_strncat(rsp, ep->core_attr, len);
len -= c_strlen(ep->core_attr);
len -= c_strlen(ep->core_attr);

h = h->next;
}
Expand Down
6 changes: 3 additions & 3 deletions app/coap/hash.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ void coap_hash(const unsigned char *s, unsigned int len, coap_key_t h) {

while (len--) {
j = sizeof(coap_key_t)-1;

while (j) {
h[j] = ((h[j] << 7) | (h[j-1] >> 1)) + h[j];
--j;
Expand All @@ -23,8 +23,8 @@ void coap_transaction_id(const uint32_t ip, const uint32_t port, const coap_pack
c_memset(h, 0, sizeof(coap_key_t));

/* Compare the transport address. */
coap_hash((const unsigned char *)&(port), sizeof(port), h);
coap_hash((const unsigned char *)&(ip), sizeof(ip), h);
coap_hash((const unsigned char *)&(port), sizeof(port), h);
coap_hash((const unsigned char *)&(ip), sizeof(ip), h);
coap_hash((const unsigned char *)(pkt->hdr.id), sizeof(pkt->hdr.id), h);
*id = ((h[0] << 8) | h[1]) ^ ((h[2] << 8) | h[3]);
}
2 changes: 1 addition & 1 deletion app/coap/node.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ coap_queue_t * coap_pop_next( coap_queue_t **queue ) { // this function is call

int coap_remove_node( coap_queue_t **queue, const coap_tid_t id){
coap_queue_t *p, *q, *node;
if ( !queue )
if ( !queue )
return 0;
if ( !*queue ) // if empty
return 0;
Expand Down
Loading

0 comments on commit 4905381

Please sign in to comment.