Thomas Aglassinger avatar Thomas Aglassinger committed 959b9f6 Merge

Merged birkenfeld/pygments-main into default

Comments (0)

Files changed (5)

pygments/lexers/_mapping.py

     'BashSessionLexer': ('pygments.lexers.shell', 'Bash Session', ('console',), ('*.sh-session',), ('application/x-shell-session',)),
     'BatchLexer': ('pygments.lexers.shell', 'Batchfile', ('bat',), ('*.bat', '*.cmd'), ('application/x-dos-batch',)),
     'BefungeLexer': ('pygments.lexers.other', 'Befunge', ('befunge',), ('*.befunge',), ('application/x-befunge',)),
+    'BlitzBasicLexer': ('pygments.lexers.compiled', 'BlitzBasic', ('blitzbasic', 'b3d', 'bplus'), ('*.bb', '*.decls'), ('text/x-bb',)),
     'BlitzMaxLexer': ('pygments.lexers.compiled', 'BlitzMax', ('blitzmax', 'bmax'), ('*.bmx',), ('text/x-bmx',)),
     'BooLexer': ('pygments.lexers.dotnet', 'Boo', ('boo',), ('*.boo',), ('text/x-boo',)),
     'BrainfuckLexer': ('pygments.lexers.other', 'Brainfuck', ('brainfuck', 'bf'), ('*.bf', '*.b'), ('application/x-brainfuck',)),
     'NSISLexer': ('pygments.lexers.other', 'NSIS', ('nsis', 'nsi', 'nsh'), ('*.nsi', '*.nsh'), ('text/x-nsis',)),
     'NasmLexer': ('pygments.lexers.asm', 'NASM', ('nasm',), ('*.asm', '*.ASM'), ('text/x-nasm',)),
     'NemerleLexer': ('pygments.lexers.dotnet', 'Nemerle', ('nemerle',), ('*.n',), ('text/x-nemerle',)),
+    'NesCLexer': ('pygments.lexers.compiled', 'nesC', ('nesc',), ('*.nc',), ('text/x-nescsrc',)),
     'NewLispLexer': ('pygments.lexers.functional', 'NewLisp', ('newlisp',), ('*.lsp', '*.nl'), ('text/x-newlisp', 'application/x-newlisp')),
     'NewspeakLexer': ('pygments.lexers.other', 'Newspeak', ('newspeak',), ('*.ns2',), ('text/x-newspeak',)),
     'NginxConfLexer': ('pygments.lexers.text', 'Nginx configuration file', ('nginx',), (), ('text/x-nginx-conf',)),
     'PostgresConsoleLexer': ('pygments.lexers.sql', 'PostgreSQL console (psql)', ('psql', 'postgresql-console', 'postgres-console'), (), ('text/x-postgresql-psql',)),
     'PostgresLexer': ('pygments.lexers.sql', 'PostgreSQL SQL dialect', ('postgresql', 'postgres'), (), ('text/x-postgresql',)),
     'PovrayLexer': ('pygments.lexers.other', 'POVRay', ('pov',), ('*.pov', '*.inc'), ('text/x-povray',)),
-    'PowerShellLexer': ('pygments.lexers.shell', 'PowerShell', ('powershell', 'posh', 'ps1', 'psm1'), ('*.ps1','*.psm1'), ('text/x-powershell',)),
+    'PowerShellLexer': ('pygments.lexers.shell', 'PowerShell', ('powershell', 'posh', 'ps1', 'psm1'), ('*.ps1', '*.psm1'), ('text/x-powershell',)),
     'PrologLexer': ('pygments.lexers.compiled', 'Prolog', ('prolog',), ('*.prolog', '*.pro', '*.pl'), ('text/x-prolog',)),
     'PropertiesLexer': ('pygments.lexers.text', 'Properties', ('properties',), ('*.properties',), ('text/x-java-properties',)),
     'ProtoBufLexer': ('pygments.lexers.other', 'Protocol Buffer', ('protobuf',), ('*.proto',), ()),

pygments/lexers/compiled.py

 from pygments.lexers.functional import OcamlLexer
 from pygments.lexers.jvm import JavaLexer, ScalaLexer
 
-__all__ = ['CLexer', 'CppLexer', 'DLexer', 'DelphiLexer', 'ECLexer', 'DylanLexer',
-           'ObjectiveCLexer', 'ObjectiveCppLexer', 'FortranLexer', 'GLShaderLexer',
-           'PrologLexer', 'CythonLexer', 'ValaLexer', 'OocLexer', 'GoLexer',
-           'FelixLexer', 'AdaLexer', 'Modula2Lexer', 'BlitzMaxLexer',
-           'NimrodLexer', 'FantomLexer', 'RustLexer', 'CudaLexer', 'MonkeyLexer',
+__all__ = ['CLexer', 'CppLexer', 'DLexer', 'DelphiLexer', 'ECLexer',
+           'NesCLexer', 'DylanLexer', 'ObjectiveCLexer', 'ObjectiveCppLexer',
+           'FortranLexer', 'GLShaderLexer', 'PrologLexer', 'CythonLexer',
+           'ValaLexer', 'OocLexer', 'GoLexer', 'FelixLexer', 'AdaLexer',
+           'Modula2Lexer', 'BlitzMaxLexer', 'BlitzBasicLexer', 'NimrodLexer',
+           'FantomLexer', 'RustLexer', 'CudaLexer', 'MonkeyLexer',
            'DylanLidLexer', 'DylanConsoleLexer', 'CobolLexer',
            'CobolFreeformatLexer', 'LogosLexer', 'ClayLexer']
 
     }
 
 
+class NesCLexer(CLexer):
+    """
+    For `nesC <https://github.com/tinyos/nesc>`_ source code with preprocessor
+    directives.
+    """
+    name = 'nesC'
+    aliases = ['nesc']
+    filenames = ['*.nc']
+    mimetypes = ['text/x-nescsrc']
+
+    tokens = {
+        'statements': [
+            (r'(abstract|as|async|atomic|call|command|component|components|'
+             r'configuration|event|extends|generic|implementation|includes|'
+             r'interface|module|new|norace|post|provides|signal|task|uses)\b',
+             Keyword),
+            (r'(nx_struct|nx_union|nx_int8_t|nx_int16_t|nx_int32_t|nx_int64_t|'
+             r'nx_uint8_t|nx_uint16_t|nx_uint32_t|nx_uint64_t)\b',
+             Keyword.Type),
+            inherit,
+        ],
+    }
+
+
 class ClayLexer(RegexLexer):
     """
     For `Clay <http://claylabs.com/clay/>`_ source.
     }
 
 
+class BlitzBasicLexer(RegexLexer):
+    """
+    For `BlitzBasic <http://blitzbasic.com>`_ source code.
+    """
+
+    name = 'BlitzBasic'
+    aliases = ['blitzbasic', 'b3d', 'bplus']
+    filenames = ['*.bb', '*.decls']
+    mimetypes = ['text/x-bb']
+
+    bb_vopwords = (r'\b(Shl|Shr|Sar|Mod|Or|And|Not|'
+                   r'Abs|Sgn|Handle|Int|Float|Str|'
+                   r'First|Last|Before|After)\b')
+    bb_sktypes = r'@{1,2}|[#$%]'
+    bb_name = r'[a-z][a-z0-9_]*'
+    bb_var = (r'(%s)(?:([ \t]*)(%s)|([ \t]*)([.])([ \t]*)(?:(%s)))?') % \
+                (bb_name, bb_sktypes, bb_name)
+
+    flags = re.MULTILINE | re.IGNORECASE
+    tokens = {
+        'root': [
+            # Text
+            (r'[ \t]+', Text),
+            # Comments
+            (r";.*?\n", Comment.Single),
+            # Data types
+            ('"', String.Double, 'string'),
+            # Numbers
+            (r'[0-9]+\.[0-9]*(?!\.)', Number.Float),
+            (r'\.[0-9]+(?!\.)', Number.Float),
+            (r'[0-9]+', Number.Integer),
+            (r'\$[0-9a-f]+', Number.Hex),
+            (r'\%[10]+', Number), # Binary
+            # Other
+            (r'(?:%s|([+\-*/~=<>^]))' % (bb_vopwords), Operator),
+            (r'[(),:\[\]\\]', Punctuation),
+            (r'\.([ \t]*)(%s)' % bb_name, Name.Label),
+            # Identifiers
+            (r'\b(New)\b([ \t]+)(%s)' % (bb_name),
+             bygroups(Keyword.Reserved, Text, Name.Class)),
+            (r'\b(Gosub|Goto)\b([ \t]+)(%s)' % (bb_name),
+             bygroups(Keyword.Reserved, Text, Name.Label)),
+            (r'\b(Object)\b([ \t]*)([.])([ \t]*)(%s)\b' % (bb_name),
+             bygroups(Operator, Text, Punctuation, Text, Name.Class)),
+            (r'\b%s\b([ \t]*)(\()' % bb_var,
+             bygroups(Name.Function, Text, Keyword.Type,Text, Punctuation,
+                      Text, Name.Class, Text, Punctuation)),
+            (r'\b(Function)\b([ \t]+)%s' % bb_var,
+             bygroups(Keyword.Reserved, Text, Name.Function, Text, Keyword.Type,
+                              Text, Punctuation, Text, Name.Class)),
+            (r'\b(Type)([ \t]+)(%s)' % (bb_name),
+             bygroups(Keyword.Reserved, Text, Name.Class)),
+            # Keywords
+            (r'\b(Pi|True|False|Null)\b', Keyword.Constant),
+            (r'\b(Local|Global|Const|Field|Dim)\b', Keyword.Declaration),
+            (r'\b(End|Return|Exit|'
+             r'Chr|Len|Asc|'
+             r'New|Delete|Insert|'
+             r'Include|'
+             r'Function|'
+             r'Type|'
+             r'If|Then|Else|ElseIf|EndIf|'
+             r'For|To|Next|Step|Each|'
+             r'While|Wend|'
+             r'Repeat|Until|Forever|'
+             r'Select|Case|Default|'
+             r'Goto|Gosub|Data|Read|Restore)\b', Keyword.Reserved),
+            # Final resolve (for variable names and such)
+#            (r'(%s)' % (bb_name), Name.Variable),
+            (bb_var, bygroups(Name.Variable, Text, Keyword.Type,
+                              Text, Punctuation, Text, Name.Class)),
+        ],
+        'string': [
+            (r'""', String.Double),
+            (r'"C?', String.Double, '#pop'),
+            (r'[^"]+', String.Double),
+        ],
+    }
+
+
 class NimrodLexer(RegexLexer):
     """
     For `Nimrod <http://nimrod-code.org/>`_ source code.

tests/examplefiles/IPDispatchC.nc

+/*
+ * "Copyright (c) 2008-2011 The Regents of the University  of California.
+ * All rights reserved."
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
+ * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
+ *
+ */
+
+/**
+ * 
+ *
+ */
+#include "IPDispatch.h"
+#include "BlipStatistics.h"
+
+configuration IPDispatchC {
+  provides {
+    interface SplitControl;
+    interface IPLower;
+    interface BlipStatistics<ip_statistics_t>;
+  }
+} implementation {
+  
+  components MainC;
+  components NoLedsC as LedsC;
+
+  /* IPDispatchP wiring -- fragment rassembly and lib6lowpan bindings */
+  components IPDispatchP;
+  components CC2420RadioC as MessageC;
+  components ReadLqiC;
+  components new TimerMilliC();
+
+  SplitControl = IPDispatchP.SplitControl;
+  IPLower = IPDispatchP;
+  BlipStatistics    = IPDispatchP;
+
+  IPDispatchP.Boot -> MainC;
+/* #else */
+/*   components ResourceSendP; */
+/*   ResourceSendP.SubSend -> MessageC; */
+/*   ResourceSendP.Resource -> MessageC.SendResource[unique("RADIO_SEND_RESOURCE")]; */
+/*   IPDispatchP.Ieee154Send -> ResourceSendP.Ieee154Send; */
+/* #endif */
+  IPDispatchP.RadioControl -> MessageC;
+
+  IPDispatchP.BarePacket -> MessageC.BarePacket;
+  IPDispatchP.Ieee154Send -> MessageC.BareSend;
+  IPDispatchP.Ieee154Receive -> MessageC.BareReceive;
+
+#ifdef LOW_POWER_LISTENING
+   IPDispatchP.LowPowerListening -> MessageC;
+#endif
+  MainC.SoftwareInit -> IPDispatchP.Init;
+
+  IPDispatchP.PacketLink -> MessageC;
+  IPDispatchP.ReadLqi -> ReadLqiC;
+  IPDispatchP.Leds -> LedsC;
+  IPDispatchP.ExpireTimer -> TimerMilliC;
+
+  components new PoolC(message_t, N_FRAGMENTS) as FragPool;
+  components new PoolC(struct send_entry, N_FRAGMENTS) as SendEntryPool;
+  components new QueueC(struct send_entry *, N_FRAGMENTS);
+  components new PoolC(struct send_info, N_CONCURRENT_SENDS) as SendInfoPool;
+  
+  IPDispatchP.FragPool -> FragPool;
+  IPDispatchP.SendEntryPool -> SendEntryPool;
+  IPDispatchP.SendInfoPool  -> SendInfoPool;
+  IPDispatchP.SendQueue -> QueueC;
+
+  components IPNeighborDiscoveryP;
+  IPDispatchP.NeighborDiscovery -> IPNeighborDiscoveryP;
+
+/*   components ICMPResponderC; */
+/* #ifdef BLIP_MULTICAST */
+/*   components MulticastP; */
+/*   components new TrickleTimerMilliC(2, 30, 2, 1); */
+/*   IP = MulticastP.IP; */
+
+/*   MainC.SoftwareInit -> MulticastP.Init; */
+/*   MulticastP.MulticastRx -> IPDispatchP.Multicast; */
+/*   MulticastP.HopHeader -> IPExtensionP.HopByHopExt[0]; */
+/*   MulticastP.TrickleTimer -> TrickleTimerMilliC.TrickleTimer[0]; */
+/*   MulticastP.IPExtensions -> IPDispatchP; */
+/* #endif */
+
+#ifdef DELUGE
+  components NWProgC;
+#endif
+
+}

tests/examplefiles/IPDispatchP.nc

+/*
+ * "Copyright (c) 2008 The Regents of the University  of California.
+ * All rights reserved."
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
+ * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
+ *
+ */
+
+#include <lib6lowpan/blip-tinyos-includes.h>
+#include <lib6lowpan/6lowpan.h>
+#include <lib6lowpan/lib6lowpan.h>
+#include <lib6lowpan/ip.h>
+#include <lib6lowpan/in_cksum.h>
+#include <lib6lowpan/ip_malloc.h>
+
+#include "blip_printf.h"
+#include "IPDispatch.h"
+#include "BlipStatistics.h"
+#include "table.h"
+
+/*
+ * Provides IP layer reception to applications on motes.
+ *
+ * @author Stephen Dawson-Haggerty <stevedh@cs.berkeley.edu>
+ */
+
+module IPDispatchP {
+  provides {
+    interface SplitControl;
+    // interface for protocols not requiring special hand-holding
+    interface IPLower;
+
+    interface BlipStatistics<ip_statistics_t>;
+
+  }
+  uses {
+    interface Boot;
+
+
+    /* link-layer wiring */
+    interface SplitControl as RadioControl;
+
+    interface Packet as BarePacket;
+    interface Send as Ieee154Send;
+    interface Receive as Ieee154Receive;
+
+    /* context lookup */
+    interface NeighborDiscovery;
+
+    interface ReadLqi;
+    interface PacketLink;
+    interface LowPowerListening;
+
+    /* buffers for outgoing fragments */
+    interface Pool<message_t> as FragPool;
+    interface Pool<struct send_info> as SendInfoPool;
+    interface Pool<struct send_entry> as SendEntryPool;
+    interface Queue<struct send_entry *> as SendQueue;
+
+    /* expire reconstruction */
+    interface Timer<TMilli> as ExpireTimer;
+
+    interface Leds;
+
+  }
+  provides interface Init;
+} implementation {
+
+#define HAVE_LOWPAN_EXTERN_MATCH_CONTEXT
+int lowpan_extern_read_context(struct in6_addr *addr, int context) {
+  return call NeighborDiscovery.getContext(context, addr);
+}
+
+int lowpan_extern_match_context(struct in6_addr *addr, uint8_t *ctx_id) {
+  return call NeighborDiscovery.matchContext(addr, ctx_id);
+}
+
+  // generally including source files like this is a no-no.  I'm doing
+  // this in the hope that the optimizer will do a better job when
+  // they're part of a component.
+#include <lib6lowpan/ieee154_header.c>
+#include <lib6lowpan/lib6lowpan.c>
+#include <lib6lowpan/lib6lowpan_4944.c>
+#include <lib6lowpan/lib6lowpan_frag.c>
+
+  enum {
+    S_RUNNING,
+    S_STOPPED,
+    S_STOPPING,
+  };
+  uint8_t state = S_STOPPED;
+  bool radioBusy;
+  uint8_t current_local_label = 0;
+  ip_statistics_t stats;
+
+  // this in theory could be arbitrarily large; however, it needs to
+  // be large enough to hold all active reconstructions, and any tags
+  // which we are dropping.  It's important to keep dropped tags
+  // around for a while, or else there are pathological situations
+  // where you continually allocate buffers for packets which will
+  // never complete.
+
+  ////////////////////////////////////////
+  //
+  //
+
+  table_t recon_cache;
+
+  // table of packets we are currently receiving fragments from, that
+  // are destined to us
+  struct lowpan_reconstruct recon_data[N_RECONSTRUCTIONS];
+
+  //
+  //
+  ////////////////////////////////////////
+
+  // task void sendTask();
+
+  void reconstruct_clear(void *ent) {
+    struct lowpan_reconstruct *recon = (struct lowpan_reconstruct *)ent;
+    memclr((uint8_t *)&recon->r_meta, sizeof(struct ip6_metadata));
+    recon->r_timeout = T_UNUSED;
+    recon->r_buf = NULL;
+  }
+
+  struct send_info *getSendInfo() {
+    struct send_info *ret = call SendInfoPool.get();
+    if (ret == NULL) return ret;
+    ret->_refcount = 1;
+    ret->upper_data = NULL;
+    ret->failed = FALSE;
+    ret->link_transmissions = 0;
+    ret->link_fragments = 0;
+    ret->link_fragment_attempts = 0;
+    return ret;
+  }
+#define SENDINFO_INCR(X) ((X)->_refcount)++
+void SENDINFO_DECR(struct send_info *si) {
+  if (--(si->_refcount) == 0) {
+    call SendInfoPool.put(si);
+  }
+}
+
+  command error_t SplitControl.start() {
+    return call RadioControl.start();
+  }
+
+  command error_t SplitControl.stop() {
+    if (!radioBusy) {
+      state = S_STOPPED;
+      return call RadioControl.stop();
+    } else {
+      // if there's a packet in the radio, wait for it to exit before
+      // stopping
+      state = S_STOPPING;
+      return SUCCESS;
+    }
+  }
+
+  event void RadioControl.startDone(error_t error) {
+#ifdef LPL_SLEEP_INTERVAL
+    call LowPowerListening.setLocalWakeupInterval(LPL_SLEEP_INTERVAL);
+#endif
+
+    if (error == SUCCESS) {
+      call Leds.led2Toggle();
+      call ExpireTimer.startPeriodic(FRAG_EXPIRE_TIME);
+      state = S_RUNNING;
+      radioBusy = FALSE;
+    }
+
+    signal SplitControl.startDone(error);
+  }
+
+  event void RadioControl.stopDone(error_t error) {
+    signal SplitControl.stopDone(error);
+  }
+
+  command error_t Init.init() {
+    // ip_malloc_init needs to be in init, not booted, because
+    // context for coap is initialised in init
+    ip_malloc_init();
+    return SUCCESS;
+  }
+
+  event void Boot.booted() {
+    call BlipStatistics.clear();
+
+    /* set up our reconstruction cache */
+    table_init(&recon_cache, recon_data, sizeof(struct lowpan_reconstruct), N_RECONSTRUCTIONS);
+    table_map(&recon_cache, reconstruct_clear);
+
+    call SplitControl.start();
+  }
+
+  /*
+   *  Receive-side code.
+   */ 
+  void deliver(struct lowpan_reconstruct *recon) {
+    struct ip6_hdr *iph = (struct ip6_hdr *)recon->r_buf;
+
+    // printf("deliver [%i]: ", recon->r_bytes_rcvd);
+    // printf_buf(recon->r_buf, recon->r_bytes_rcvd);
+
+    /* the payload length field is always compressed, have to put it back here */
+    iph->ip6_plen = htons(recon->r_bytes_rcvd - sizeof(struct ip6_hdr));
+    signal IPLower.recv(iph, (void *)(iph + 1), &recon->r_meta);
+
+    // printf("ip_free(%p)\n", recon->r_buf);
+    ip_free(recon->r_buf);
+    recon->r_timeout = T_UNUSED;
+    recon->r_buf = NULL;
+  }
+
+  /*
+   * Bulletproof recovery logic is very important to make sure we
+   * don't get wedged with no free buffers.
+   * 
+   * The table is managed as follows:
+   *  - unused entries are marked T_UNUSED
+   *  - entries which 
+   *     o have a buffer allocated
+   *     o have had a fragment reception before we fired
+   *     are marked T_ACTIVE
+   *  - entries which have not had a fragment reception during the last timer period
+   *     and were active are marked T_ZOMBIE
+   *  - zombie receptions are deleted: their buffer is freed and table entry marked unused.
+   *  - when a fragment is dropped, it is entered into the table as T_FAILED1.
+   *     no buffer is allocated
+   *  - when the timer fires, T_FAILED1 entries are aged to T_FAILED2.
+   * - T_FAILED2 entries are deleted.  Incomming fragments with tags
+   *     that are marked either FAILED1 or FAILED2 are dropped; this
+   *     prevents us from allocating a buffer for a packet which we
+   *     have already dropped fragments from.
+   *
+   */ 
+  void reconstruct_age(void *elt) {
+    struct lowpan_reconstruct *recon = (struct lowpan_reconstruct *)elt;
+    if (recon->r_timeout != T_UNUSED) 
+      printf("recon src: 0x%x tag: 0x%x buf: %p recvd: %i/%i\n", 
+                 recon->r_source_key, recon->r_tag, recon->r_buf, 
+                 recon->r_bytes_rcvd, recon->r_size);
+    switch (recon->r_timeout) {
+    case T_ACTIVE:
+      recon->r_timeout = T_ZOMBIE; break; // age existing receptions
+    case T_FAILED1:
+      recon->r_timeout = T_FAILED2; break; // age existing receptions
+    case T_ZOMBIE:
+    case T_FAILED2:
+      // deallocate the space for reconstruction
+      printf("timing out buffer: src: %i tag: %i\n", recon->r_source_key, recon->r_tag);
+      if (recon->r_buf != NULL) {
+        printf("ip_free(%p)\n", recon->r_buf);
+        ip_free(recon->r_buf);
+      }
+      recon->r_timeout = T_UNUSED;
+      recon->r_buf = NULL;
+      break;
+    }
+  }
+
+  void ip_print_heap() {
+#ifdef PRINTFUART_ENABLED
+    bndrt_t *cur = (bndrt_t *)heap;
+    while (((uint8_t *)cur)  - heap < IP_MALLOC_HEAP_SIZE) {
+      printf ("heap region start: %p length: %u used: %u\n", 
+                  cur, (*cur & IP_MALLOC_LEN), (*cur & IP_MALLOC_INUSE) >> 15);
+      cur = (bndrt_t *)(((uint8_t *)cur) + ((*cur) & IP_MALLOC_LEN));
+    }
+#endif
+  }
+
+  event void ExpireTimer.fired() {
+    table_map(&recon_cache, reconstruct_age);
+
+    
+    printf("Frag pool size: %i\n", call FragPool.size());
+    printf("SendInfo pool size: %i\n", call SendInfoPool.size());
+    printf("SendEntry pool size: %i\n", call SendEntryPool.size());
+    printf("Forward queue length: %i\n", call SendQueue.size());
+    ip_print_heap();
+    printfflush();
+  }
+
+  /*
+   * allocate a structure for recording information about incomming fragments.
+   */
+
+  struct lowpan_reconstruct *get_reconstruct(uint16_t key, uint16_t tag) {
+    struct lowpan_reconstruct *ret = NULL;
+    int i;
+
+    // printf("get_reconstruct: %x %i\n", key, tag);
+
+    for (i = 0; i < N_RECONSTRUCTIONS; i++) {
+      struct lowpan_reconstruct *recon = (struct lowpan_reconstruct *)&recon_data[i];
+
+      if (recon->r_tag == tag &&
+          recon->r_source_key == key) {
+
+        if (recon->r_timeout > T_UNUSED) {          
+          recon->r_timeout = T_ACTIVE;
+          ret = recon;
+          goto done;
+
+        } else if (recon->r_timeout < T_UNUSED) {
+          // if we have already tried and failed to get a buffer, we
+          // need to drop remaining fragments.
+          ret = NULL;
+          goto done;
+        }
+      }
+      if (recon->r_timeout == T_UNUSED) 
+        ret = recon;
+    }
+  done:
+    // printf("got%p\n", ret);
+    return ret;
+  }
+
+  event message_t *Ieee154Receive.receive(message_t *msg, void *msg_payload, uint8_t len) {
+    struct packed_lowmsg lowmsg;
+    struct ieee154_frame_addr frame_address;
+    uint8_t *buf = msg_payload;
+
+    // printf(" -- RECEIVE -- len : %i\n", len);
+
+    BLIP_STATS_INCR(stats.rx_total);
+
+    /* unpack the 802.15.4 address fields */
+    buf  = unpack_ieee154_hdr(msg_payload, &frame_address);
+    len -= buf - (uint8_t *)msg_payload;
+
+    /* unpack and 6lowpan headers */
+    lowmsg.data = buf;
+    lowmsg.len  = len;
+    lowmsg.headers = getHeaderBitmap(&lowmsg);
+    if (lowmsg.headers == LOWMSG_NALP) {
+      goto fail;
+    }
+
+    if (hasFrag1Header(&lowmsg) || hasFragNHeader(&lowmsg)) {
+      // start reassembly
+      int rv;
+      struct lowpan_reconstruct *recon;
+      uint16_t tag, source_key;
+
+      source_key = ieee154_hashaddr(&frame_address.ieee_src);
+      getFragDgramTag(&lowmsg, &tag);
+      recon = get_reconstruct(source_key, tag);
+      if (!recon) {
+        goto fail;
+      }
+
+      /* fill in metadata: on fragmented packets, it applies to the
+         first fragment only  */
+      memcpy(&recon->r_meta.sender, &frame_address.ieee_src,
+             sizeof(ieee154_addr_t));
+      recon->r_meta.lqi = call ReadLqi.readLqi(msg);
+      recon->r_meta.rssi = call ReadLqi.readRssi(msg);
+
+      if (hasFrag1Header(&lowmsg)) {
+        if (recon->r_buf != NULL) goto fail;
+        rv = lowpan_recon_start(&frame_address, recon, buf, len);
+      } else {
+        rv = lowpan_recon_add(recon, buf, len);
+      }
+        
+      if (rv < 0) {
+        recon->r_timeout = T_FAILED1;
+        goto fail;
+      } else {
+        // printf("start recon buf: %p\n", recon->r_buf);
+        recon->r_timeout = T_ACTIVE;
+        recon->r_source_key = source_key;
+        recon->r_tag = tag;
+      }
+
+      if (recon->r_size == recon->r_bytes_rcvd) {
+        deliver(recon);
+      }
+
+    } else {
+      /* no fragmentation, just deliver it */
+      int rv;
+      struct lowpan_reconstruct recon;
+
+      /* fill in metadata */
+      memcpy(&recon.r_meta.sender, &frame_address.ieee_src, 
+             sizeof(ieee154_addr_t));
+      recon.r_meta.lqi = call ReadLqi.readLqi(msg);
+      recon.r_meta.rssi = call ReadLqi.readRssi(msg);
+
+      buf = getLowpanPayload(&lowmsg);
+      if ((rv = lowpan_recon_start(&frame_address, &recon, buf, len)) < 0) {
+        goto fail;
+      }
+
+      if (recon.r_size == recon.r_bytes_rcvd) {
+        deliver(&recon);
+      } else {
+        // printf("ip_free(%p)\n", recon.r_buf);
+        ip_free(recon.r_buf);
+      }
+    }
+    goto done;
+  fail:
+    BLIP_STATS_INCR(stats.rx_drop);
+  done:
+    return msg;
+  }
+
+
+  /*
+   * Send-side functionality
+   */
+  task void sendTask() {
+    struct send_entry *s_entry;
+
+    // printf("sendTask() - sending\n");
+
+    if (radioBusy || state != S_RUNNING) return;
+    if (call SendQueue.empty()) return;
+    // this does not dequeue
+    s_entry = call SendQueue.head();
+
+#ifdef LPL_SLEEP_INTERVAL
+    call LowPowerListening.setRemoteWakeupInterval(s_entry->msg,
+            call LowPowerListening.getLocalWakeupInterval());
+#endif
+
+    if (s_entry->info->failed) {
+      dbg("Drops", "drops: sendTask: dropping failed fragment\n");
+      goto fail;
+    }
+
+    if ((call Ieee154Send.send(s_entry->msg,
+                               call BarePacket.payloadLength(s_entry->msg))) != SUCCESS) {
+      dbg("Drops", "drops: sendTask: send failed\n");
+      goto fail;
+    } else {
+      radioBusy = TRUE;
+    }
+
+    return;
+  fail:
+    printf("SEND FAIL\n");
+    post sendTask();
+    BLIP_STATS_INCR(stats.tx_drop);
+
+    // deallocate the memory associated with this request.
+    // other fragments associated with this packet will get dropped.
+    s_entry->info->failed = TRUE;
+    SENDINFO_DECR(s_entry->info);
+    call FragPool.put(s_entry->msg);
+    call SendEntryPool.put(s_entry);
+    call SendQueue.dequeue();
+  }
+  
+
+  /*
+   *  it will pack the message into the fragment pool and enqueue
+   *  those fragments for sending
+   *
+   * it will set
+   *  - payload length
+   *  - version, traffic class and flow label
+   *
+   * the source and destination IP addresses must be set by higher
+   * layers.
+   */
+  command error_t IPLower.send(struct ieee154_frame_addr *frame_addr,
+                               struct ip6_packet *msg,
+                               void  *data) {
+    struct lowpan_ctx ctx;
+    struct send_info  *s_info;
+    struct send_entry *s_entry;
+    message_t *outgoing;
+
+    int frag_len = 1;
+    error_t rc = SUCCESS;
+
+    if (state != S_RUNNING) {
+      return EOFF;
+    }
+
+    /* set version to 6 in case upper layers forgot */
+    msg->ip6_hdr.ip6_vfc &= ~IPV6_VERSION_MASK;
+    msg->ip6_hdr.ip6_vfc |= IPV6_VERSION;
+
+    ctx.tag = current_local_label++;
+    ctx.offset = 0;
+
+    s_info = getSendInfo();
+    if (s_info == NULL) {
+      rc = ERETRY;
+      goto cleanup_outer;
+    }
+    s_info->upper_data = data;
+
+    while (frag_len > 0) {
+      s_entry  = call SendEntryPool.get();
+      outgoing = call FragPool.get();
+
+      if (s_entry == NULL || outgoing == NULL) {
+        if (s_entry != NULL)
+          call SendEntryPool.put(s_entry);
+        if (outgoing != NULL)
+          call FragPool.put(outgoing);
+        // this will cause any fragments we have already enqueued to
+        // be dropped by the send task.
+        s_info->failed = TRUE;
+        printf("drops: IP send: no fragments\n");
+        rc = ERETRY;
+        goto done;
+      }
+
+      call BarePacket.clear(outgoing);
+      frag_len = lowpan_frag_get(call Ieee154Send.getPayload(outgoing, 0),
+                                 call BarePacket.maxPayloadLength(),
+                                 msg,
+                                 frame_addr,
+                                 &ctx);
+      if (frag_len < 0) {
+        printf(" get frag error: %i\n", frag_len);
+      }
+
+      printf("fragment length: %i offset: %i\n", frag_len, ctx.offset);
+      call BarePacket.setPayloadLength(outgoing, frag_len);
+
+      if (frag_len <= 0) {
+        call FragPool.put(outgoing);
+        call SendEntryPool.put(s_entry);
+        goto done;
+      }
+
+      if (call SendQueue.enqueue(s_entry) != SUCCESS) {
+        BLIP_STATS_INCR(stats.encfail);
+        s_info->failed = TRUE;
+        printf("drops: IP send: enqueue failed\n");
+        goto done;
+      }
+
+      s_info->link_fragments++;
+      s_entry->msg = outgoing;
+      s_entry->info = s_info;
+
+      /* configure the L2 */
+      if (frame_addr->ieee_dst.ieee_mode == IEEE154_ADDR_SHORT &&
+          frame_addr->ieee_dst.i_saddr == IEEE154_BROADCAST_ADDR) {
+        call PacketLink.setRetries(s_entry->msg, 0);
+      } else {
+        call PacketLink.setRetries(s_entry->msg, BLIP_L2_RETRIES);
+      }
+      call PacketLink.setRetryDelay(s_entry->msg, BLIP_L2_DELAY);
+
+      SENDINFO_INCR(s_info);}
+       
+    // printf("got %i frags\n", s_info->link_fragments);
+  done:
+    BLIP_STATS_INCR(stats.sent);
+    SENDINFO_DECR(s_info);
+    post sendTask();
+  cleanup_outer:
+    return rc;
+  }
+
+  event void Ieee154Send.sendDone(message_t *msg, error_t error) {
+    struct send_entry *s_entry = call SendQueue.head();
+
+    radioBusy = FALSE;
+
+    // printf("sendDone: %p %i\n", msg, error);
+
+    if (state == S_STOPPING) {
+      call RadioControl.stop();
+      state = S_STOPPED;
+      goto done;
+    }
+    
+    s_entry->info->link_transmissions += (call PacketLink.getRetries(msg));
+    s_entry->info->link_fragment_attempts++;
+
+    if (!call PacketLink.wasDelivered(msg)) {
+      printf("sendDone: was not delivered! (%i tries)\n", 
+                 call PacketLink.getRetries(msg));
+      s_entry->info->failed = TRUE;
+      signal IPLower.sendDone(s_entry->info);
+/*       if (s_entry->info->policy.dest[0] != 0xffff) */
+/*         dbg("Drops", "drops: sendDone: frag was not delivered\n"); */
+      // need to check for broadcast frames
+      // BLIP_STATS_INCR(stats.tx_drop);
+    } else if (s_entry->info->link_fragment_attempts == 
+               s_entry->info->link_fragments) {
+      signal IPLower.sendDone(s_entry->info);
+    }
+
+  done:
+    // kill off any pending fragments
+    SENDINFO_DECR(s_entry->info);
+    call FragPool.put(s_entry->msg);
+    call SendEntryPool.put(s_entry);
+    call SendQueue.dequeue();
+
+    post sendTask();
+  }
+
+#if 0
+  command struct tlv_hdr *IPExtensions.findTlv(struct ip6_ext *ext, uint8_t tlv_val) {
+    int len = ext->len - sizeof(struct ip6_ext);
+    struct tlv_hdr *tlv = (struct tlv_hdr *)(ext + 1);
+    while (len > 0) {
+      if (tlv->type == tlv_val) return tlv;
+      if (tlv->len == 0) return NULL;
+      tlv = (struct tlv_hdr *)(((uint8_t *)tlv) + tlv->len);
+      len -= tlv->len;
+    }
+    return NULL;
+  }
+#endif
+
+
+  /*
+   * BlipStatistics interface
+   */
+  command void BlipStatistics.get(ip_statistics_t *statistics) {
+#ifdef BLIP_STATS_IP_MEM
+    stats.fragpool = call FragPool.size();
+    stats.sendinfo = call SendInfoPool.size();
+    stats.sendentry= call SendEntryPool.size();
+    stats.sndqueue = call SendQueue.size();
+    stats.heapfree = ip_malloc_freespace();
+    printf("frag: %i sendinfo: %i sendentry: %i sendqueue: %i heap: %i\n",
+               stats.fragpool,
+               stats.sendinfo,
+               stats.sendentry,
+               stats.sndqueue,
+               stats.heapfree);
+#endif
+    memcpy(statistics, &stats, sizeof(ip_statistics_t));
+
+  }
+
+  command void BlipStatistics.clear() {
+    memclr((uint8_t *)&stats, sizeof(ip_statistics_t));
+  }
+
+/*   default event void IP.recv[uint8_t nxt_hdr](struct ip6_hdr *iph, */
+/*                                               void *payload, */
+/*                                               struct ip_metadata *meta) { */
+/*   } */
+
+/*   default event void Multicast.recv[uint8_t scope](struct ip6_hdr *iph, */
+/*                                                    void *payload, */
+/*                                                    struct ip_metadata *meta) { */
+/*   } */
+}

tests/examplefiles/test.bb

+
+;foobar!
+
+;Include "blurg/blurg.bb"
+
+Const ca = $10000000 ; Hex
+Const cb = %10101010 ; Binary
+Global ga$ = "blargh"
+Local a = 124, b$ = "abcdef"
+
+Function name_123#(zorp$, ll = False, blah#, waffles% = 100)
+	Return 235.7804 ; comment
+End Function
+Function TestString$()
+End Function
+
+Function hub(blah$, abc = Pi)
+End Function
+Function Blar%()
+	Local aa %, ab # ,ac #, ad# ,ae$,af% ; Intentional mangling
+	Local ba#, bb.TBlarf , bc%,bd#,be. TFooBar,ff = True
+End Function
+
+abc()
+
+Function abc()
+	Print "abc"	; I cannot find a way to parse these as function calls without messing something up
+	Print		; Anyhow, they're generally not used in this way
+	Goto Eww_Goto
+	.Eww_Goto
+End Function
+
+Type TBlarf
+End Type
+
+Type TFooBar
+End Type
+
+Local myinst.MyClass = New MyClass
+TestMethod(myinst)
+
+Type MyClass
+	
+	Field m_foo.MyClass
+	Field m_bar.MyClass
+	
+;	abc
+;	def
+End Type
+
+Function TestMethod(self.MyClass) ; foobar
+	self\m_foo = self
+	self\m_bar = Object.MyClass(Handle self\m_foo)
+	Yell self\m_foo\m_bar\m_foo\m_bar
+End Function
+
+Function Yell(self.MyClass)
+	Print("huzzah!")
+End Function
+
+Function Wakka$(foo$)
+	Return foo + "bar"
+End Function
+
+
+Print("blah " + "blah " + "blah.")
+
+Local i : For i = 0 To 10 Step 1
+	Print("Index: " + i)
+Next
+Local array$[5]
+array[0] = "foo": array[1] = "bar":array[2] = "11":array[3] = "22":array[4] = "33"
+For i = 0 To 4
+	Local value$ = array[i]
+	Print("Value: " + value)
+Next
+
+Local foobar = Not (1 Or (2 And (4 Shl 5 Shr 6)) Sar 7) Mod (8+2)
+Local az = 1234567890
+az = az + 1
+az = az - 2
+az  = az* 3
+az = az/ 4
+az = az And 5
+az = az Or 6
+az= ~ 7
+az  = az Shl 8
+az= az  Shr 9
+az  = az Sar 10
+az = az Mod 11
+az = ((10-5+2/4*2)>(((8^2)) < 2)) And 12 Or 2
+
+
+;~IDEal Editor Parameters:
+;~C#Blitz3D
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.