Changes in / [a505021:8c50aed]


Ignore:
Files:
20 added
47 deleted
87 edited

Legend:

Unmodified
Added
Removed
  • Jenkinsfile

    ra505021 r8c50aed  
    215215
    216216                //Then publish the results
    217                 do_plot(Settings.RunBenchmark && Settings.Publish, 'compile'        , groupCompile    , false, 'Compilation')
    218                 do_plot(Settings.RunBenchmark && Settings.Publish, 'compile.diff'   , groupCompile    , true , 'Compilation (relative)')
    219                 do_plot(Settings.RunBenchmark && Settings.Publish, 'ctxswitch'      , groupConcurrency, false, 'Context Switching')
    220                 do_plot(Settings.RunBenchmark && Settings.Publish, 'ctxswitch.diff' , groupConcurrency, true , 'Context Switching (relative)')
    221                 do_plot(Settings.RunBenchmark && Settings.Publish, 'mutex'          , groupConcurrency, false, 'Mutual Exclusion')
    222                 do_plot(Settings.RunBenchmark && Settings.Publish, 'mutex.diff'     , groupConcurrency, true , 'Mutual Exclusion (relative)')
    223                 do_plot(Settings.RunBenchmark && Settings.Publish, 'scheduling'     , groupConcurrency, false, 'Internal and External Scheduling')
    224                 do_plot(Settings.RunBenchmark && Settings.Publish, 'scheduling.diff', groupConcurrency, true , 'Internal and External Scheduling (relative)')
     217                do_plot(Settings.RunBenchmark && Settings.Publish, 'compile'       , groupCompile    , false, 'Compilation')
     218                do_plot(Settings.RunBenchmark && Settings.Publish, 'compile.diff'  , groupCompile    , true , 'Compilation (relative)')
     219                do_plot(Settings.RunBenchmark && Settings.Publish, 'ctxswitch'     , groupConcurrency, false, 'Context Switching')
     220                do_plot(Settings.RunBenchmark && Settings.Publish, 'ctxswitch.diff', groupConcurrency, true , 'Context Switching (relative)')
     221                do_plot(Settings.RunBenchmark && Settings.Publish, 'mutex'         , groupConcurrency, false, 'Mutual Exclusion')
     222                do_plot(Settings.RunBenchmark && Settings.Publish, 'mutex.diff'    , groupConcurrency, true , 'Mutual Exclusion (relative)')
     223                do_plot(Settings.RunBenchmark && Settings.Publish, 'signal'        , groupConcurrency, false, 'Internal and External Scheduling')
     224                do_plot(Settings.RunBenchmark && Settings.Publish, 'signal.diff'   , groupConcurrency, true , 'Internal and External Scheduling (relative)')
    225225        }
    226226}
  • benchmark/Makefile.am

    ra505021 r8c50aed  
    3030BENCH_V_UPP = $(__bench_v_UPP_$(__quiet))
    3131BENCH_V_GOC = $(__bench_v_GOC_$(__quiet))
    32 BENCH_V_PY = $(__bench_v_PY_$(__quiet))
    3332BENCH_V_RUSTC = $(__bench_v_RUSTC_$(__quiet))
    3433BENCH_V_NODEJS = $(__bench_v_NODEJS_$(__quiet))
     
    4847__bench_v_UPP_verbose = $(AM_V_UPP)
    4948__bench_v_GOC_verbose = $(AM_V_GOC)
    50 __bench_v_PY_verbose = $(AM_V_PY)
    51 __bench_v_RUSTC_verbose = $(AM_V_RUST)
     49__bench_v_RUSTC_verbose = $(AM_V_RUSTC)
    5250__bench_v_NODEJS_verbose = $(AM_V_NODEJS)
    5351__bench_v_JAVAC_verbose = $(AM_V_JAVAC)
     
    7472        echo "int main() { return 0; }" > ${@}
    7573
    76 .SILENT:                # do not print recipe
     74#.SILENT:               # do not print recipe
     75.ONESHELL:              # use one shell to execute recipe
    7776.NOTPARALLEL:
    78 .PHONY: jenkins cleancsv
     77.PHONY: compile.csv basic.csv ctxswitch.csv mutex.csv schedint.csv
    7978
    8079## =========================================================================================================
     
    143142FIX_NEW_LINES = cat $@ | tr "\n" "\t" | sed -r 's/\t,/,/' | tr "\t" "\n" > $@
    144143
    145 cleancsv:
    146         rm -f compile.csv basic.csv ctxswitch.csv mutex.csv scheduling.csv
    147 
    148 jenkins$(EXEEXT): cleancsv
     144jenkins$(EXEEXT):
    149145@DOifskipcompile@
    150146        +make compile.csv
    151147        -+make compile.diff.csv
    152148@DOendif@
     149        +make basic.csv
     150        -+make basic.diff.csv
    153151        +make ctxswitch.csv
    154152        -+make ctxswitch.diff.csv
    155153        +make mutex.csv
    156154        -+make mutex.diff.csv
    157         +make scheduling.csv
    158         -+make scheduling.diff.csv
     155        +make schedint.csv
     156        -+make schedint.diff.csv
    159157@DOifskipcompile@
    160158        cat compile.csv
    161159        -cat compile.diff.csv
    162160@DOendif@
     161        cat basic.csv
     162        -cat basic.diff.csv
    163163        cat ctxswitch.csv
    164164        -cat ctxswitch.diff.csv
    165165        cat mutex.csv
    166166        -cat mutex.diff.csv
    167         cat scheduling.csv
    168         -cat scheduling.diff.csv
     167        cat schedint.csv
     168        -cat schedint.diff.csv
    169169
    170170compile.csv:
    171         echo "building $@"
    172171        echo "array,attributes,empty,expression,io,monitor,operators,typeof" > $@
    173172        +make TIME_FORMAT='%e,' PRINT_FORMAT='' compile-array.make >> $@
     
    181180        $(srcdir)/fixcsv.sh $@
    182181
     182basic.csv:
     183        echo "generator,coroutine,thread" > $@
     184        +make basic-cfa_generator.runquiet >> $@ && echo -n ',' >> $@
     185        +make basic-cfa_coroutine.runquiet >> $@ && echo -n ',' >> $@
     186        +make basic-cfa_thread.runquiet >> $@
     187        $(srcdir)/fixcsv.sh $@
     188
    183189ctxswitch.csv:
    184         echo "building $@"
    185190        echo "generator,coroutine,thread" > $@
    186191        +make ctxswitch-cfa_generator.runquiet >> $@ && echo -n ',' >> $@
     
    190195
    191196mutex.csv:
    192         echo "building $@"
    193197        echo "1-monitor,2-monitor" > $@
    194198        +make mutex-cfa1.runquiet >> $@ && echo -n ',' >> $@
     
    196200        $(srcdir)/fixcsv.sh $@
    197201
    198 scheduling.csv:
    199         echo "building $@"
     202schedint.csv:
    200203        echo "schedint-1,schedint-2,schedext-1,schedext-2" > $@
    201204        +make schedint-cfa1.runquiet >> $@ && echo -n ',' >> $@
     
    286289
    287290ctxswitch-python_coroutine$(EXEEXT):
    288         $(BENCH_V_PY)echo "#!/bin/sh" > a.out
     291        echo "#!/bin/sh" > a.out
    289292        echo "python3.7 $(srcdir)/ctxswitch/python_cor.py" >> a.out
    290293        chmod a+x a.out
    291294
    292295ctxswitch-nodejs_coroutine$(EXEEXT):
    293         $(BENCH_V_NODEJS)echo "#!/bin/sh" > a.out
     296        echo "#!/bin/sh" > a.out
    294297        echo "nodejs $(srcdir)/ctxswitch/node_cor.js" >> a.out
    295298        chmod a+x a.out
    296299
    297300ctxswitch-nodejs_await$(EXEEXT):
    298         $(BENCH_V_NODEJS)echo "#!/bin/sh" > a.out
     301        echo "#!/bin/sh" > a.out
    299302        echo "nodejs $(srcdir)/ctxswitch/node_await.js" >> a.out
    300303        chmod a+x a.out
     
    449452
    450453creation-python_coroutine$(EXEEXT):
    451         $(BENCH_V_PY)echo "#!/bin/sh" > a.out
     454        echo "#!/bin/sh" > a.out
    452455        echo "python3.7 $(srcdir)/creation/python_cor.py" >> a.out
    453456        chmod a+x a.out
    454457
    455458creation-nodejs_coroutine$(EXEEXT):
    456         $(BENCH_V_NODEJS)echo "#!/bin/sh" > a.out
     459        echo "#!/bin/sh" > a.out
    457460        echo "nodejs $(srcdir)/creation/node_cor.js" >> a.out
    458461        chmod a+x a.out
  • benchmark/Makefile.in

    ra505021 r8c50aed  
    368368am__v_GOC_0 = @echo "  GOC     " $@;
    369369am__v_GOC_1 =
    370 AM_V_PY = $(am__v_PY_@AM_V@)
    371 am__v_PY_ = $(am__v_PY_@AM_DEFAULT_V@)
    372 am__v_PY_0 = @echo "  PYTHON  " $@;
    373 am__v_PY_1 =
    374370AM_V_RUST = $(am__v_RUST_@AM_V@)
    375371am__v_RUST_ = $(am__v_RUST_@AM_DEFAULT_V@)
    376 am__v_RUST_0 = @echo "  RUST    " $@;
     372am__v_RUST_0 = @echo "  RUST     " $@;
    377373am__v_RUST_1 =
    378374AM_V_NODEJS = $(am__v_NODEJS_@AM_V@)
    379375am__v_NODEJS_ = $(am__v_NODEJS_@AM_DEFAULT_V@)
    380 am__v_NODEJS_0 = @echo "  NODEJS  " $@;
     376am__v_NODEJS_0 = @echo "  NODEJS     " $@;
    381377am__v_NODEJS_1 =
    382378AM_V_JAVAC = $(am__v_JAVAC_@AM_V@)
     
    394390BENCH_V_UPP = $(__bench_v_UPP_$(__quiet))
    395391BENCH_V_GOC = $(__bench_v_GOC_$(__quiet))
    396 BENCH_V_PY = $(__bench_v_PY_$(__quiet))
    397392BENCH_V_RUSTC = $(__bench_v_RUSTC_$(__quiet))
    398393BENCH_V_NODEJS = $(__bench_v_NODEJS_$(__quiet))
     
    411406__bench_v_UPP_verbose = $(AM_V_UPP)
    412407__bench_v_GOC_verbose = $(AM_V_GOC)
    413 __bench_v_PY_verbose = $(AM_V_PY)
    414 __bench_v_RUSTC_verbose = $(AM_V_RUST)
     408__bench_v_RUSTC_verbose = $(AM_V_RUSTC)
    415409__bench_v_NODEJS_verbose = $(AM_V_NODEJS)
    416410__bench_v_JAVAC_verbose = $(AM_V_JAVAC)
     
    790784        echo "int main() { return 0; }" > ${@}
    791785
    792 .SILENT:                # do not print recipe
     786#.SILENT:               # do not print recipe
     787.ONESHELL:              # use one shell to execute recipe
    793788.NOTPARALLEL:
    794 .PHONY: jenkins cleancsv
     789.PHONY: compile.csv basic.csv ctxswitch.csv mutex.csv schedint.csv
    795790
    796791all : basic$(EXEEXT) ctxswitch$(EXEEXT) mutex$(EXEEXT) schedint$(EXEEXT) schedext$(EXEEXT) creation$(EXEEXT)
     
    822817        +make -C ${abs_top_builddir}/tools repeat
    823818
    824 cleancsv:
    825         rm -f compile.csv basic.csv ctxswitch.csv mutex.csv scheduling.csv
    826 
    827 jenkins$(EXEEXT): cleancsv
     819jenkins$(EXEEXT):
    828820@DOifskipcompile@
    829821        +make compile.csv
    830822        -+make compile.diff.csv
    831823@DOendif@
     824        +make basic.csv
     825        -+make basic.diff.csv
    832826        +make ctxswitch.csv
    833827        -+make ctxswitch.diff.csv
    834828        +make mutex.csv
    835829        -+make mutex.diff.csv
    836         +make scheduling.csv
    837         -+make scheduling.diff.csv
     830        +make schedint.csv
     831        -+make schedint.diff.csv
    838832@DOifskipcompile@
    839833        cat compile.csv
    840834        -cat compile.diff.csv
    841835@DOendif@
     836        cat basic.csv
     837        -cat basic.diff.csv
    842838        cat ctxswitch.csv
    843839        -cat ctxswitch.diff.csv
    844840        cat mutex.csv
    845841        -cat mutex.diff.csv
    846         cat scheduling.csv
    847         -cat scheduling.diff.csv
     842        cat schedint.csv
     843        -cat schedint.diff.csv
    848844
    849845compile.csv:
    850         echo "building $@"
    851846        echo "array,attributes,empty,expression,io,monitor,operators,typeof" > $@
    852847        +make TIME_FORMAT='%e,' PRINT_FORMAT='' compile-array.make >> $@
     
    860855        $(srcdir)/fixcsv.sh $@
    861856
     857basic.csv:
     858        echo "generator,coroutine,thread" > $@
     859        +make basic-cfa_generator.runquiet >> $@ && echo -n ',' >> $@
     860        +make basic-cfa_coroutine.runquiet >> $@ && echo -n ',' >> $@
     861        +make basic-cfa_thread.runquiet >> $@
     862        $(srcdir)/fixcsv.sh $@
     863
    862864ctxswitch.csv:
    863         echo "building $@"
    864865        echo "generator,coroutine,thread" > $@
    865866        +make ctxswitch-cfa_generator.runquiet >> $@ && echo -n ',' >> $@
     
    869870
    870871mutex.csv:
    871         echo "building $@"
    872872        echo "1-monitor,2-monitor" > $@
    873873        +make mutex-cfa1.runquiet >> $@ && echo -n ',' >> $@
     
    875875        $(srcdir)/fixcsv.sh $@
    876876
    877 scheduling.csv:
    878         echo "building $@"
     877schedint.csv:
    879878        echo "schedint-1,schedint-2,schedext-1,schedext-2" > $@
    880879        +make schedint-cfa1.runquiet >> $@ && echo -n ',' >> $@
     
    932931
    933932ctxswitch-python_coroutine$(EXEEXT):
    934         $(BENCH_V_PY)echo "#!/bin/sh" > a.out
     933        echo "#!/bin/sh" > a.out
    935934        echo "python3.7 $(srcdir)/ctxswitch/python_cor.py" >> a.out
    936935        chmod a+x a.out
    937936
    938937ctxswitch-nodejs_coroutine$(EXEEXT):
    939         $(BENCH_V_NODEJS)echo "#!/bin/sh" > a.out
     938        echo "#!/bin/sh" > a.out
    940939        echo "nodejs $(srcdir)/ctxswitch/node_cor.js" >> a.out
    941940        chmod a+x a.out
    942941
    943942ctxswitch-nodejs_await$(EXEEXT):
    944         $(BENCH_V_NODEJS)echo "#!/bin/sh" > a.out
     943        echo "#!/bin/sh" > a.out
    945944        echo "nodejs $(srcdir)/ctxswitch/node_await.js" >> a.out
    946945        chmod a+x a.out
     
    10861085
    10871086creation-python_coroutine$(EXEEXT):
    1088         $(BENCH_V_PY)echo "#!/bin/sh" > a.out
     1087        echo "#!/bin/sh" > a.out
    10891088        echo "python3.7 $(srcdir)/creation/python_cor.py" >> a.out
    10901089        chmod a+x a.out
    10911090
    10921091creation-nodejs_coroutine$(EXEEXT):
    1093         $(BENCH_V_NODEJS)echo "#!/bin/sh" > a.out
     1092        echo "#!/bin/sh" > a.out
    10941093        echo "nodejs $(srcdir)/creation/node_cor.js" >> a.out
    10951094        chmod a+x a.out
  • doc/theses/thierry_delisle_PhD/code/relaxed_list.cpp

    ra505021 r8c50aed  
    99#include <vector>
    1010
    11 #include <getopt.h>
    1211#include <unistd.h>
    1312#include <sys/sysinfo.h>
     
    2221
    2322        int value;
    24         int id;
    25 
    26         Node() { creates++; }
    27         Node(int value): value(value) { creates++; }
    28         ~Node() { destroys++; }
     23        Node(int value): value(value) {
     24                creates++;
     25        }
     26
     27        ~Node() {
     28                destroys++;
     29        }
    2930};
    3031
     
    3233std::atomic_size_t Node::destroys = { 0 };
    3334
     35static const constexpr int nodes_per_threads = 128;
     36struct NodeArray {
     37        __attribute__((aligned(64))) Node * array[nodes_per_threads];
     38        __attribute__((aligned(64))) char pad;
     39};
     40
    3441bool enable_stats = false;
    35 
    36 template<>
    37 thread_local relaxed_list<Node>::TLS relaxed_list<Node>::tls = {};
    38 
    39 template<>
    40 relaxed_list<Node> * relaxed_list<Node>::head = nullptr;
    41 
    42 #ifndef NO_STATS
    43 template<>
    44 relaxed_list<Node>::GlobalStats relaxed_list<Node>::global_stats = {};
    45 #endif
    46 
    47 // ================================================================================================
    48 //                        UTILS
    49 // ================================================================================================
    5042
    5143struct local_stat_t {
     
    5547        size_t crc_in  = 0;
    5648        size_t crc_out = 0;
    57         size_t valmax = 0;
    58         size_t valmin = 100000000ul;
    5949};
    6050
    61 struct global_stat_t {
    62         std::atomic_size_t in  = { 0 };
    63         std::atomic_size_t out = { 0 };
    64         std::atomic_size_t empty = { 0 };
    65         std::atomic_size_t crc_in  = { 0 };
    66         std::atomic_size_t crc_out = { 0 };
    67         std::atomic_size_t valmax = { 0 };
    68         std::atomic_size_t valmin = { 100000000ul };
    69 };
    70 
    71 void atomic_max(std::atomic_size_t & target, size_t value) {
    72         for(;;) {
    73                 size_t expect = target.load(std::memory_order_relaxed);
    74                 if(value <= expect) return;
    75                 bool success = target.compare_exchange_strong(expect, value);
    76                 if(success) return;
    77         }
    78 }
    79 
    80 void atomic_min(std::atomic_size_t & target, size_t value) {
    81         for(;;) {
    82                 size_t expect = target.load(std::memory_order_relaxed);
    83                 if(value >= expect) return;
    84                 bool success = target.compare_exchange_strong(expect, value);
    85                 if(success) return;
    86         }
    87 }
    88 
    89 void tally_stats(global_stat_t & global, local_stat_t & local) {
    90 
    91         global.in    += local.in;
    92         global.out   += local.out;
    93         global.empty += local.empty;
    94 
    95         global.crc_in  += local.crc_in;
    96         global.crc_out += local.crc_out;
    97 
    98         atomic_max(global.valmax, local.valmax);
    99         atomic_min(global.valmin, local.valmin);
    100 
    101         relaxed_list<Node>::stats_tls_tally();
    102 }
    103 
    104 void waitfor(double & duration, barrier_t & barrier, std::atomic_bool & done) {
     51__attribute__((noinline)) void run_body(
     52        std::atomic<bool>& done,
     53        Random & rand,
     54        Node * (&my_nodes)[128],
     55        local_stat_t & local,
     56        relaxed_list<Node> & list
     57) {
     58        while(__builtin_expect(!done.load(std::memory_order_relaxed), true)) {
     59                int idx = rand.next() % nodes_per_threads;
     60                if (auto node = my_nodes[idx]) {
     61                        local.crc_in += node->value;
     62                        list.push(node);
     63                        my_nodes[idx] = nullptr;
     64                        local.in++;
     65                }
     66                else if(auto node = list.pop()) {
     67                        local.crc_out += node->value;
     68                        my_nodes[idx] = node;
     69                        local.out++;
     70                }
     71                else {
     72                        local.empty++;
     73                }
     74        }
     75}
     76
     77void run(unsigned nthread, unsigned nqueues, unsigned fill, double duration) {
     78        // List being tested
     79        relaxed_list<Node> list = { nthread * nqueues };
     80
     81        // Barrier for synchronization
     82        barrier_t barrier(nthread + 1);
     83
     84        // Data to check everything is OK
     85        struct {
     86                std::atomic_size_t in  = { 0 };
     87                std::atomic_size_t out = { 0 };
     88                std::atomic_size_t empty = { 0 };
     89                std::atomic_size_t crc_in  = { 0 };
     90                std::atomic_size_t crc_out = { 0 };
     91                struct {
     92                        struct {
     93                                std::atomic_size_t attempt = { 0 };
     94                                std::atomic_size_t success = { 0 };
     95                        } push;
     96                        struct {
     97                                std::atomic_size_t attempt = { 0 };
     98                                std::atomic_size_t success = { 0 };
     99                        } pop;
     100                } pick;
     101        } global;
     102
     103        // Flag to signal termination
     104        std::atomic_bool done  = { false };
     105
     106        // Prep nodes
     107        std::cout << "Initializing ";
     108        size_t nnodes  = 0;
     109        size_t npushed = 0;
     110        NodeArray all_nodes[nthread];
     111        for(auto & nodes : all_nodes) {
     112                Random rand(rdtscl());
     113                for(auto & node : nodes.array) {
     114                        auto r = rand.next() % 100;
     115                        if(r < fill) {
     116                                node = new Node(rand.next() % 100);
     117                                nnodes++;
     118                        } else {
     119                                node = nullptr;
     120                        }
     121                }
     122
     123                for(int i = 0; i < 10; i++) {
     124                        int idx = rand.next() % nodes_per_threads;
     125                        if (auto node = nodes.array[idx]) {
     126                                global.crc_in += node->value;
     127                                list.push(node);
     128                                npushed++;
     129                                nodes.array[idx] = nullptr;
     130                        }
     131                }
     132        }
     133
     134        std::cout << nnodes << " nodes " << fill << "% (" << npushed << " pushed)" << std::endl;
     135
     136        enable_stats = true;
     137
     138        std::thread * threads[nthread];
     139        unsigned i = 1;
     140        for(auto & t : threads) {
     141                auto & my_nodes = all_nodes[i - 1].array;
     142                t = new std::thread([&done, &list, &barrier, &global, &my_nodes](unsigned tid) {
     143                        Random rand(tid + rdtscl());
     144
     145                        local_stat_t local;
     146
     147                        // affinity(tid);
     148
     149                        barrier.wait(tid);
     150
     151                        // EXPERIMENT START
     152
     153                        run_body(done, rand, my_nodes, local, list);
     154
     155                        // EXPERIMENT END
     156
     157                        barrier.wait(tid);
     158
     159                        global.in    += local.in;
     160                        global.out   += local.out;
     161                        global.empty += local.empty;
     162
     163                        for(auto node : my_nodes) {
     164                                delete node;
     165                        }
     166
     167                        global.crc_in  += local.crc_in;
     168                        global.crc_out += local.crc_out;
     169
     170                        global.pick.push.attempt += relaxed_list<Node>::tls.pick.push.attempt;
     171                        global.pick.push.success += relaxed_list<Node>::tls.pick.push.success;
     172                        global.pick.pop .attempt += relaxed_list<Node>::tls.pick.pop.attempt;
     173                        global.pick.pop .success += relaxed_list<Node>::tls.pick.pop.success;
     174                }, i++);
     175        }
     176
    105177        std::cout << "Starting" << std::endl;
    106178        auto before = Clock::now();
     
    124196        duration = durr.count();
    125197        std::cout << "\rClosing down" << std::endl;
    126 }
    127 
    128 void waitfor(double & duration, barrier_t & barrier, const std::atomic_size_t & count) {
    129         std::cout << "Starting" << std::endl;
    130         auto before = Clock::now();
    131         barrier.wait(0);
    132 
    133         while(true) {
    134                 usleep(100000);
    135                 size_t c = count.load();
    136                 if( c == 0 ) {
    137                         break;
    138                 }
    139                 std::cout << "\r" << c;
    140                 std::cout.flush();
    141         }
    142 
    143         barrier.wait(0);
    144         auto after = Clock::now();
    145         duration_t durr = after - before;
    146         duration = durr.count();
    147         std::cout << "\rClosing down" << std::endl;
    148 }
    149 
    150 void print_stats(double duration, unsigned nthread, global_stat_t & global) {
     198
     199        for(auto t : threads) {
     200                t->join();
     201                delete t;
     202        }
     203
     204        enable_stats = false;
     205
     206        while(auto node = list.pop()) {
     207                global.crc_out += node->value;
     208                delete node;
     209        }
     210
    151211        assert(Node::creates == Node::destroys);
    152212        assert(global.crc_in == global.crc_out);
     
    164224        std::cout << "Ops/sec       : " << ops_sec << "\n";
    165225        std::cout << "Total ops     : " << ops << "(" << global.in << "i, " << global.out << "o, " << global.empty << "e)\n";
    166         if(global.valmax != 0) {
    167                 std::cout << "Max runs      : " << global.valmax << "\n";
    168                 std::cout << "Min runs      : " << global.valmin << "\n";
    169         }
    170226        #ifndef NO_STATS
    171                 relaxed_list<Node>::stats_print(std::cout);
     227                double push_sur = (100.0 * double(global.pick.push.success) / global.pick.push.attempt);
     228                double pop_sur  = (100.0 * double(global.pick.pop .success) / global.pick.pop .attempt);
     229                std::cout << "Push Pick %   : " << push_sur << "(" << global.pick.push.success << " / " << global.pick.push.attempt << ")\n";
     230                std::cout << "Pop  Pick %   : " << pop_sur  << "(" << global.pick.pop .success << " / " << global.pick.pop .attempt << ")\n";
    172231        #endif
    173232}
    174233
    175 void save_fairness(const int data[], int factor, unsigned nthreads, size_t columns, size_t rows, const std::string & output);
    176 
    177 // ================================================================================================
    178 //                        EXPERIMENTS
    179 // ================================================================================================
    180 
    181 // ================================================================================================
    182 __attribute__((noinline)) void runChurn_body(
    183         std::atomic<bool>& done,
    184         Random & rand,
    185         Node * my_nodes[],
    186         unsigned nslots,
    187         local_stat_t & local,
    188         relaxed_list<Node> & list
    189 ) {
    190         while(__builtin_expect(!done.load(std::memory_order_relaxed), true)) {
    191                 int idx = rand.next() % nslots;
    192                 if (auto node = my_nodes[idx]) {
    193                         local.crc_in += node->value;
    194                         list.push(node);
    195                         my_nodes[idx] = nullptr;
    196                         local.in++;
    197                 }
    198                 else if(auto node = list.pop()) {
    199                         local.crc_out += node->value;
    200                         my_nodes[idx] = node;
    201                         local.out++;
    202                 }
    203                 else {
    204                         local.empty++;
    205                 }
    206         }
    207 }
    208 
    209 void runChurn(unsigned nthread, unsigned nqueues, double duration, unsigned nnodes, const unsigned nslots) {
    210         std::cout << "Churn Benchmark" << std::endl;
    211         assert(nnodes <= nslots);
    212         // List being tested
    213 
    214         // Barrier for synchronization
    215         barrier_t barrier(nthread + 1);
    216 
    217         // Data to check everything is OK
    218         global_stat_t global;
    219 
    220         // Flag to signal termination
    221         std::atomic_bool done  = { false };
    222 
    223         // Prep nodes
    224         std::cout << "Initializing ";
    225         size_t npushed = 0;
    226         relaxed_list<Node> list = { nthread * nqueues };
    227         {
    228                 Node** all_nodes[nthread];
    229                 for(auto & nodes : all_nodes) {
    230                         nodes = new __attribute__((aligned(64))) Node*[nslots + 8];
    231                         Random rand(rdtscl());
    232                         for(unsigned i = 0; i < nnodes; i++) {
    233                                 nodes[i] = new Node(rand.next() % 100);
    234                         }
    235 
    236                         for(unsigned i = nnodes; i < nslots; i++) {
    237                                 nodes[i] = nullptr;
    238                         }
    239 
    240                         for(int i = 0; i < 10 && i < (int)nslots; i++) {
    241                                 int idx = rand.next() % nslots;
    242                                 if (auto node = nodes[idx]) {
    243                                         global.crc_in += node->value;
    244                                         list.push(node);
    245                                         npushed++;
    246                                         nodes[idx] = nullptr;
    247                                 }
    248                         }
    249                 }
    250 
    251                 std::cout << nnodes << " nodes (" << nslots << " slots)" << std::endl;
    252 
    253                 enable_stats = true;
    254 
    255                 std::thread * threads[nthread];
    256                 unsigned i = 1;
    257                 for(auto & t : threads) {
    258                         auto & my_nodes = all_nodes[i - 1];
    259                         t = new std::thread([&done, &list, &barrier, &global, &my_nodes, nslots](unsigned tid) {
    260                                 Random rand(tid + rdtscl());
    261 
    262                                 local_stat_t local;
    263 
    264                                 // affinity(tid);
    265 
    266                                 barrier.wait(tid);
    267 
    268                                 // EXPERIMENT START
    269 
    270                                 runChurn_body(done, rand, my_nodes, nslots, local, list);
    271 
    272                                 // EXPERIMENT END
    273 
    274                                 barrier.wait(tid);
    275 
    276                                 tally_stats(global, local);
    277 
    278                                 for(unsigned i = 0; i < nslots; i++) {
    279                                         delete my_nodes[i];
    280                                 }
    281                         }, i++);
    282                 }
    283 
    284                 waitfor(duration, barrier, done);
    285 
    286                 for(auto t : threads) {
    287                         t->join();
    288                         delete t;
    289                 }
    290 
    291                 enable_stats = false;
    292 
    293                 while(auto node = list.pop()) {
    294                         global.crc_out += node->value;
    295                         delete node;
    296                 }
    297 
    298                 for(auto nodes : all_nodes) {
    299                         delete[] nodes;
    300                 }
    301         }
    302 
    303         print_stats(duration, nthread, global);
    304 }
    305 
    306 // ================================================================================================
    307 __attribute__((noinline)) void runPingPong_body(
    308         std::atomic<bool>& done,
    309         Node initial_nodes[],
    310         unsigned nnodes,
    311         local_stat_t & local,
    312         relaxed_list<Node> & list
    313 ) {
    314         Node * nodes[nnodes];
    315         {
    316                 unsigned i = 0;
    317                 for(auto & n : nodes) {
    318                         n = &initial_nodes[i++];
    319                 }
    320         }
    321 
    322         while(__builtin_expect(!done.load(std::memory_order_relaxed), true)) {
    323 
    324                 for(Node * & node : nodes) {
    325                         local.crc_in += node->value;
    326                         list.push(node);
    327                         local.in++;
    328                 }
    329 
    330                 // -----
    331 
    332                 for(Node * & node : nodes) {
    333                         node = list.pop();
    334                         assert(node);
    335                         local.crc_out += node->value;
    336                         local.out++;
    337                 }
    338         }
    339 }
    340 
    341 void runPingPong(unsigned nthread, unsigned nqueues, double duration, unsigned nnodes) {
    342         std::cout << "PingPong Benchmark" << std::endl;
    343 
    344 
    345         // Barrier for synchronization
    346         barrier_t barrier(nthread + 1);
    347 
    348         // Data to check everything is OK
    349         global_stat_t global;
    350 
    351         // Flag to signal termination
    352         std::atomic_bool done  = { false };
    353 
    354         std::cout << "Initializing ";
    355         // List being tested
    356         relaxed_list<Node> list = { nthread * nqueues };
    357         {
    358                 enable_stats = true;
    359 
    360                 std::thread * threads[nthread];
    361                 unsigned i = 1;
    362                 for(auto & t : threads) {
    363                         t = new std::thread([&done, &list, &barrier, &global, nnodes](unsigned tid) {
    364                                 Random rand(tid + rdtscl());
    365 
    366                                 Node nodes[nnodes];
    367                                 for(auto & n : nodes) {
    368                                         n.value = (int)rand.next() % 100;
    369                                 }
    370 
    371                                 local_stat_t local;
    372 
    373                                 // affinity(tid);
    374 
    375                                 barrier.wait(tid);
    376 
    377                                 // EXPERIMENT START
    378 
    379                                 runPingPong_body(done, nodes, nnodes, local, list);
    380 
    381                                 // EXPERIMENT END
    382 
    383                                 barrier.wait(tid);
    384 
    385                                 tally_stats(global, local);
    386                         }, i++);
    387                 }
    388 
    389                 waitfor(duration, barrier, done);
    390 
    391                 for(auto t : threads) {
    392                         t->join();
    393                         delete t;
    394                 }
    395 
    396                 enable_stats = false;
    397         }
    398 
    399         print_stats(duration, nthread, global);
    400 }
    401 
    402 // ================================================================================================
    403 __attribute__((noinline)) void runFairness_body(
    404         unsigned tid,
    405         size_t width,
    406         size_t length,
    407         int output[],
    408         std::atomic_size_t & count,
    409         Node initial_nodes[],
    410         unsigned nnodes,
    411         local_stat_t & local,
    412         relaxed_list<Node> & list
    413 ) {
    414         Node * nodes[nnodes];
    415         {
    416                 unsigned i = 0;
    417                 for(auto & n : nodes) {
    418                         n = &initial_nodes[i++];
    419                 }
    420         }
    421 
    422         while(__builtin_expect(0 != count.load(std::memory_order_relaxed), true)) {
    423 
    424                 for(Node * & node : nodes) {
    425                         local.crc_in += node->id;
    426                         list.push(node);
    427                         local.in++;
    428                 }
    429 
    430                 // -----
    431 
    432                 for(Node * & node : nodes) {
    433                         node = list.pop();
    434                         assert(node);
    435 
    436                         if (unsigned(node->value) < length) {
    437                                 size_t idx = (node->value * width) + node->id;
    438                                 assert(idx < (width * length));
    439                                 output[idx] = tid;
    440                         }
    441 
    442                         node->value++;
    443                         if(unsigned(node->value) == length) count--;
    444 
    445                         local.crc_out += node->id;
    446                         local.out++;
    447                 }
    448         }
    449 }
    450 
    451 void runFairness(unsigned nthread, unsigned nqueues, double duration, unsigned nnodes, const std::string & output) {
    452         std::cout << "Fairness Benchmark, outputing to : " << output << std::endl;
    453 
    454         // Barrier for synchronization
    455         barrier_t barrier(nthread + 1);
    456 
    457         // Data to check everything is OK
    458         global_stat_t global;
    459 
    460         std::cout << "Initializing ";
    461 
    462         // Check fairness by creating a png of where the threads ran
    463         size_t width = nthread * nnodes;
    464         size_t length = 100000;
    465 
    466         std::unique_ptr<int[]> data_out { new int[width * length] };
    467 
    468         // Flag to signal termination
    469         std::atomic_size_t count = width;
    470 
    471         // List being tested
    472         relaxed_list<Node> list = { nthread * nqueues };
    473         {
    474                 enable_stats = true;
    475 
    476                 std::thread * threads[nthread];
    477                 unsigned i = 1;
    478                 for(auto & t : threads) {
    479                         t = new std::thread([&count, &list, &barrier, &global, nnodes, width, length, data_out = data_out.get()](unsigned tid) {
    480                                 unsigned int start = (tid - 1) * nnodes;
    481                                 Node nodes[nnodes];
    482                                 for(auto & n : nodes) {
    483                                         n.id = start;
    484                                         n.value = 0;
    485                                         start++;
    486                                 }
    487 
    488                                 local_stat_t local;
    489 
    490                                 // affinity(tid);
    491 
    492                                 barrier.wait(tid);
    493 
    494                                 // EXPERIMENT START
    495 
    496                                 runFairness_body(tid, width, length, data_out, count, nodes, nnodes, local, list);
    497 
    498                                 // EXPERIMENT END
    499 
    500                                 barrier.wait(tid);
    501 
    502                                 for(const auto & n : nodes) {
    503                                         local.valmax = max(local.valmax, size_t(n.value));
    504                                         local.valmin = min(local.valmin, size_t(n.value));
    505                                 }
    506 
    507                                 tally_stats(global, local);
    508                         }, i++);
    509                 }
    510 
    511                 waitfor(duration, barrier, count);
    512 
    513                 for(auto t : threads) {
    514                         t->join();
    515                         delete t;
    516                 }
    517 
    518                 enable_stats = false;
    519         }
    520 
    521         print_stats(duration, nthread, global);
    522 
    523         save_fairness(data_out.get(), 100, nthread, width, length, output);
    524 }
    525 
    526 // ================================================================================================
    527 
    528 bool iequals(const std::string& a, const std::string& b)
    529 {
    530     return std::equal(a.begin(), a.end(),
    531                       b.begin(), b.end(),
    532                       [](char a, char b) {
    533                           return std::tolower(a) == std::tolower(b);
    534                       });
     234void usage(char * argv[]) {
     235        std::cerr << argv[0] << ": [DURATION (FLOAT:SEC)] [NTHREADS] [NQUEUES] [FILL]" << std::endl;;
     236        std::exit(1);
    535237}
    536238
     
    539241        double duration   = 5.0;
    540242        unsigned nthreads = 2;
    541         unsigned nqueues  = 4;
    542         unsigned nnodes   = 100;
    543         unsigned nslots   = 100;
    544         std::string out   = "fairness.png";
    545 
    546         enum {
    547                 Churn,
    548                 PingPong,
    549                 Fairness,
    550                 NONE
    551         } benchmark = NONE;
     243        unsigned nqueues  = 2;
     244        unsigned fill     = 100;
    552245
    553246        std::cout.imbue(std::locale(""));
    554247
    555         for(;;) {
    556                 static struct option options[] = {
    557                         {"duration",  required_argument, 0, 'd'},
    558                         {"nthreads",  required_argument, 0, 't'},
    559                         {"nqueues",   required_argument, 0, 'q'},
    560                         {"benchmark", required_argument, 0, 'b'},
    561                         {0, 0, 0, 0}
    562                 };
    563 
    564                 int idx = 0;
    565                 int opt = getopt_long(argc, argv, "d:t:q:b:", options, &idx);
    566 
    567                 std::string arg = optarg ? optarg : "";
    568                 size_t len = 0;
    569                 switch(opt) {
    570                         // Exit Case
    571                         case -1:
    572                                 /* paranoid */ assert(optind <= argc);
    573                                 switch(benchmark) {
    574                                 case NONE:
    575                                         std::cerr << "Must specify a benchmark" << std::endl;
    576                                         goto usage;
    577                                 case PingPong:
    578                                         nnodes = 1;
    579                                         nslots = 1;
    580                                         switch(argc - optind) {
    581                                         case 0: break;
    582                                         case 1:
    583                                                 try {
    584                                                         arg = optarg = argv[optind];
    585                                                         nnodes = stoul(optarg, &len);
    586                                                         if(len != arg.size()) { throw std::invalid_argument(""); }
    587                                                 } catch(std::invalid_argument &) {
    588                                                         std::cerr << "Number of nodes must be a positive integer, was " << arg << std::endl;
    589                                                         goto usage;
    590                                                 }
    591                                                 break;
    592                                         default:
    593                                                 std::cerr << "'PingPong' benchmark doesn't accept more than 2 extra arguments" << std::endl;
    594                                                 goto usage;
    595                                         }
    596                                         break;
    597                                 case Churn:
    598                                         nnodes = 100;
    599                                         nslots = 100;
    600                                         switch(argc - optind) {
    601                                         case 0: break;
    602                                         case 1:
    603                                                 try {
    604                                                         arg = optarg = argv[optind];
    605                                                         nnodes = stoul(optarg, &len);
    606                                                         if(len != arg.size()) { throw std::invalid_argument(""); }
    607                                                         nslots = nnodes;
    608                                                 } catch(std::invalid_argument &) {
    609                                                         std::cerr << "Number of nodes must be a positive integer, was " << arg << std::endl;
    610                                                         goto usage;
    611                                                 }
    612                                                 break;
    613                                         case 2:
    614                                                 try {
    615                                                         arg = optarg = argv[optind];
    616                                                         nnodes = stoul(optarg, &len);
    617                                                         if(len != arg.size()) { throw std::invalid_argument(""); }
    618                                                 } catch(std::invalid_argument &) {
    619                                                         std::cerr << "Number of nodes must be a positive integer, was " << arg << std::endl;
    620                                                         goto usage;
    621                                                 }
    622                                                 try {
    623                                                         arg = optarg = argv[optind + 1];
    624                                                         nslots = stoul(optarg, &len);
    625                                                         if(len != arg.size()) { throw std::invalid_argument(""); }
    626                                                 } catch(std::invalid_argument &) {
    627                                                         std::cerr << "Number of slots must be a positive integer, was " << arg << std::endl;
    628                                                         goto usage;
    629                                                 }
    630                                                 break;
    631                                         default:
    632                                                 std::cerr << "'Churn' benchmark doesn't accept more than 2 extra arguments" << std::endl;
    633                                                 goto usage;
    634                                         }
    635                                         break;
    636                                 case Fairness:
    637                                         nnodes = 1;
    638                                         switch(argc - optind) {
    639                                         case 0: break;
    640                                         case 1:
    641                                                 arg = optarg = argv[optind];
    642                                                 out = arg;
    643                                                 break;
    644                                         default:
    645                                                 std::cerr << "'Churn' benchmark doesn't accept more than 2 extra arguments" << std::endl;
    646                                                 goto usage;
    647                                         }
    648                                 }
    649                                 goto run;
    650                         // Benchmarks
    651                         case 'b':
    652                                 if(benchmark != NONE) {
    653                                         std::cerr << "Only when benchmark can be run" << std::endl;
    654                                         goto usage;
    655                                 }
    656                                 if(iequals(arg, "churn")) {
    657                                         benchmark = Churn;
    658                                         break;
    659                                 }
    660                                 if(iequals(arg, "pingpong")) {
    661                                         benchmark = PingPong;
    662                                         break;
    663                                 }
    664                                 if(iequals(arg, "fairness")) {
    665                                         benchmark = Fairness;
    666                                         break;
    667                                 }
    668                                 std::cerr << "Unkown benchmark " << arg << std::endl;
    669                                 goto usage;
    670                         // Numeric Arguments
    671                         case 'd':
    672                                 try {
    673                                         duration = stod(optarg, &len);
    674                                         if(len != arg.size()) { throw std::invalid_argument(""); }
    675                                 } catch(std::invalid_argument &) {
    676                                         std::cerr << "Duration must be a valid double, was " << arg << std::endl;
    677                                         goto usage;
    678                                 }
    679                                 break;
    680                         case 't':
    681                                 try {
    682                                         nthreads = stoul(optarg, &len);
    683                                         if(len != arg.size()) { throw std::invalid_argument(""); }
    684                                 } catch(std::invalid_argument &) {
    685                                         std::cerr << "Number of threads must be a positive integer, was " << arg << std::endl;
    686                                         goto usage;
    687                                 }
    688                                 break;
    689                         case 'q':
    690                                 try {
    691                                         nqueues = stoul(optarg, &len);
    692                                         if(len != arg.size()) { throw std::invalid_argument(""); }
    693                                 } catch(std::invalid_argument &) {
    694                                         std::cerr << "Number of queues must be a positive integer, was " << arg << std::endl;
    695                                         goto usage;
    696                                 }
    697                                 break;
    698                         // Other cases
    699                         default: /* ? */
    700                                 std::cerr << opt << std::endl;
    701                         usage:
    702                                 std::cerr << "Usage: " << argv[0] << ": [options] -b churn [NNODES] [NSLOTS = NNODES]" << std::endl;
    703                                 std::cerr << "  or:  " << argv[0] << ": [options] -b pingpong [NNODES]" << std::endl;
    704                                 std::cerr << std::endl;
    705                                 std::cerr << "  -d, --duration=DURATION  Duration of the experiment, in seconds" << std::endl;
    706                                 std::cerr << "  -t, --nthreads=NTHREADS  Number of kernel threads" << std::endl;
    707                                 std::cerr << "  -q, --nqueues=NQUEUES    Number of queues per threads" << std::endl;
    708                                 std::exit(1);
    709                 }
    710         }
    711         run:
     248        switch (argc)
     249        {
     250        case 5:
     251                fill = std::stoul(argv[4]);
     252                [[fallthrough]];
     253        case 4:
     254                nqueues = std::stoul(argv[3]);
     255                [[fallthrough]];
     256        case 3:
     257                nthreads = std::stoul(argv[2]);
     258                [[fallthrough]];
     259        case 2:
     260                duration = std::stod(argv[1]);
     261                if( duration <= 0.0 ) {
     262                        std::cerr << "Duration must be positive, was " << argv[1] << "(" << duration << ")" << std::endl;
     263                        usage(argv);
     264                }
     265                [[fallthrough]];
     266        case 1:
     267                break;
     268        default:
     269                usage(argv);
     270                break;
     271        }
    712272
    713273        check_cache_line_size();
    714274
    715275        std::cout << "Running " << nthreads << " threads (" << (nthreads * nqueues) << " queues) for " << duration << " seconds" << std::endl;
    716         switch(benchmark) {
    717                 case Churn:
    718                         runChurn(nthreads, nqueues, duration, nnodes, nslots);
    719                         break;
    720                 case PingPong:
    721                         runPingPong(nthreads, nqueues, duration, nnodes);
    722                         break;
    723                 case Fairness:
    724                         runFairness(nthreads, nqueues, duration, nnodes, out);
    725                         break;
    726                 default:
    727                         abort();
    728         }
     276        run(nthreads, nqueues, fill, duration);
     277
    729278        return 0;
    730279}
    731280
     281template<>
     282thread_local relaxed_list<Node>::TLS relaxed_list<Node>::tls = {};
     283
     284template<>
     285relaxed_list<Node>::intrusive_queue_t::stat::Dif relaxed_list<Node>::intrusive_queue_t::stat::dif = {};
     286
    732287const char * __my_progname = "Relaxed List";
    733 
    734 struct rgb_t {
    735     double r;       // a fraction between 0 and 1
    736     double g;       // a fraction between 0 and 1
    737     double b;       // a fraction between 0 and 1
    738 };
    739 
    740 struct hsv_t {
    741     double h;       // angle in degrees
    742     double s;       // a fraction between 0 and 1
    743     double v;       // a fraction between 0 and 1
    744 };
    745 
    746 rgb_t hsv2rgb(hsv_t in) {
    747         double hh, p, q, t, ff;
    748         long   i;
    749         rgb_t  out;
    750 
    751         if(in.s <= 0.0) {       // < is bogus, just shuts up warnings
    752                 out.r = in.v;
    753                 out.g = in.v;
    754                 out.b = in.v;
    755                 return out;
    756         }
    757         hh = in.h;
    758         if(hh >= 360.0) hh = 0.0;
    759         hh /= 60.0;
    760         i = (long)hh;
    761         ff = hh - i;
    762         p = in.v * (1.0 - in.s);
    763         q = in.v * (1.0 - (in.s * ff));
    764         t = in.v * (1.0 - (in.s * (1.0 - ff)));
    765 
    766         switch(i) {
    767         case 0:
    768                 out.r = in.v;
    769                 out.g = t;
    770                 out.b = p;
    771                 break;
    772         case 1:
    773                 out.r = q;
    774                 out.g = in.v;
    775                 out.b = p;
    776                 break;
    777         case 2:
    778                 out.r = p;
    779                 out.g = in.v;
    780                 out.b = t;
    781                 break;
    782 
    783         case 3:
    784                 out.r = p;
    785                 out.g = q;
    786                 out.b = in.v;
    787                 break;
    788         case 4:
    789                 out.r = t;
    790                 out.g = p;
    791                 out.b = in.v;
    792                 break;
    793         case 5:
    794         default:
    795                 out.r = in.v;
    796                 out.g = p;
    797                 out.b = q;
    798                 break;
    799         }
    800         return out;
    801 }
    802 
    803 void save_fairness(const int data[], int factor, unsigned nthreads, size_t columns, size_t rows, const std::string & output) {
    804         std::ofstream os(output);
    805         os << "<html>\n";
    806         os << "<head>\n";
    807         os << "<style>\n";
    808         os << "</style>\n";
    809         os << "</head>\n";
    810         os << "<body>\n";
    811         os << "<table style=\"width=100%\">\n";
    812 
    813         size_t idx = 0;
    814         for(size_t r = 0ul; r < rows; r++) {
    815                 os << "<tr>\n";
    816                 for(size_t c = 0ul; c < columns; c++) {
    817                         os << "<td class=\"custom custom" << data[idx] << "\"></td>\n";
    818                         idx++;
    819                 }
    820                 os << "</tr>\n";
    821         }
    822 
    823         os << "</table>\n";
    824         os << "</body>\n";
    825         os << "</html>\n";
    826         os << std::endl;
    827 }
    828 
    829 #include <png.h>
    830 #include <setjmp.h>
    831 
    832 /*
    833 void save_fairness(const int data[], int factor, unsigned nthreads, size_t columns, size_t rows, const std::string & output) {
    834         int width  = columns * factor;
    835         int height = rows / factor;
    836 
    837         int code = 0;
    838         int idx = 0;
    839         FILE *fp = NULL;
    840         png_structp png_ptr = NULL;
    841         png_infop info_ptr = NULL;
    842         png_bytep row = NULL;
    843 
    844         // Open file for writing (binary mode)
    845         fp = fopen(output.c_str(), "wb");
    846         if (fp == NULL) {
    847                 fprintf(stderr, "Could not open file %s for writing\n", output.c_str());
    848                 code = 1;
    849                 goto finalise;
    850         }
    851 
    852            // Initialize write structure
    853         png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    854         if (png_ptr == NULL) {
    855                 fprintf(stderr, "Could not allocate write struct\n");
    856                 code = 1;
    857                 goto finalise;
    858         }
    859 
    860         // Initialize info structure
    861         info_ptr = png_create_info_struct(png_ptr);
    862         if (info_ptr == NULL) {
    863                 fprintf(stderr, "Could not allocate info struct\n");
    864                 code = 1;
    865                 goto finalise;
    866         }
    867 
    868         // Setup Exception handling
    869         if (setjmp(png_jmpbuf(png_ptr))) {
    870                 fprintf(stderr, "Error during png creation\n");
    871                 code = 1;
    872                 goto finalise;
    873         }
    874 
    875         png_init_io(png_ptr, fp);
    876 
    877         // Write header (8 bit colour depth)
    878         png_set_IHDR(png_ptr, info_ptr, width, height,
    879                 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,
    880                 PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
    881 
    882         png_write_info(png_ptr, info_ptr);
    883 
    884         // Allocate memory for one row (3 bytes per pixel - RGB)
    885         row = (png_bytep) malloc(3 * width * sizeof(png_byte));
    886 
    887         // Write image data
    888         int x, y;
    889         for (y=0 ; y<height ; y++) {
    890                 for (x=0 ; x<width ; x++) {
    891                         auto & r = row[(x * 3) + 0];
    892                         auto & g = row[(x * 3) + 1];
    893                         auto & b = row[(x * 3) + 2];
    894                         assert(idx < (rows * columns));
    895                         int color = data[idx] - 1;
    896                         assert(color < nthreads);
    897                         assert(color >= 0);
    898                         idx++;
    899 
    900                         double angle = double(color) / double(nthreads);
    901 
    902                         auto c = hsv2rgb({ 360.0 * angle, 0.8, 0.8 });
    903 
    904                         r = char(c.r * 255.0);
    905                         g = char(c.g * 255.0);
    906                         b = char(c.b * 255.0);
    907 
    908                 }
    909                 png_write_row(png_ptr, row);
    910         }
    911 
    912         assert(idx == (rows * columns));
    913 
    914         // End write
    915         png_write_end(png_ptr, NULL);
    916 
    917         finalise:
    918         if (fp != NULL) fclose(fp);
    919         if (info_ptr != NULL) png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
    920         if (png_ptr != NULL) png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
    921         if (row != NULL) free(row);
    922 }
    923 */
  • doc/theses/thierry_delisle_PhD/code/relaxed_list.hpp

    ra505021 r8c50aed  
    3737};
    3838
    39 static inline bool bts(std::atomic_size_t & target, size_t bit ) {
    40         //*
    41         int result = 0;
    42         asm volatile(
    43                 "LOCK btsq %[bit], %[target]\n\t"
    44                 :"=@ccc" (result)
    45                 : [target] "m" (target), [bit] "r" (bit)
    46         );
    47         return result != 0;
    48         /*/
    49         size_t mask = 1ul << bit;
    50         size_t ret = target.fetch_or(mask, std::memory_order_relaxed);
    51         return (ret & mask) != 0;
    52         //*/
    53 }
    54 
    55 static inline bool btr(std::atomic_size_t & target, size_t bit ) {
    56         //*
    57         int result = 0;
    58         asm volatile(
    59                 "LOCK btrq %[bit], %[target]\n\t"
    60                 :"=@ccc" (result)
    61                 : [target] "m" (target), [bit] "r" (bit)
    62         );
    63         return result != 0;
    64         /*/
    65         size_t mask = 1ul << bit;
    66         size_t ret = target.fetch_and(~mask, std::memory_order_relaxed);
    67         return (ret & mask) != 0;
    68         //*/
    69 }
    7039
    7140extern bool enable_stats;
     
    7948                size_t attempt = 0;
    8049                size_t success = 0;
    81                 size_t mask_attempt = 0;
    82         } pop;
    83 };
    84 
    85 struct empty_stat {
    86         struct {
    87                 size_t value = 0;
    88                 size_t count = 0;
    89         } push;
    90         struct {
    91                 size_t value = 0;
    92                 size_t count = 0;
    9350        } pop;
    9451};
     
    10562        static_assert(std::is_same<decltype(node_t::_links), _LinksFields_t<node_t>>::value, "Node must have a links field");
    10663
     64
    10765public:
    10866        relaxed_list(unsigned numLists)
    109                 : lists(new intrusive_queue_t[numLists])
     67                : numNonEmpty{0}
     68                , lists(new intrusive_queue_t[numLists])
    11069                , numLists(numLists)
    111         {
    112                 assertf(7 * 8 * 8 >= numLists, "List currently only supports 448 sublists");
    113                 // assert(sizeof(*this) == 128);
    114                 std::cout << "Constructing Relaxed List with " << numLists << std::endl;
    115 
     70        {}
     71
     72        ~relaxed_list() {
     73                lists.reset();
    11674                #ifndef NO_STATS
    117                         if(head) this->next = head;
    118                         head = this;
     75                        std::cout << "Difference   : "
     76                                << ssize_t(double(intrusive_queue_t::stat::dif.value) / intrusive_queue_t::stat::dif.num  ) << " avg\t"
     77                                << intrusive_queue_t::stat::dif.max << "max" << std::endl;
    11978                #endif
    120         }
    121 
    122         ~relaxed_list() {
    123                 std::cout << "Destroying Relaxed List" << std::endl;
    124                 lists.reset();
    12579        }
    12680
     
    13084                while(true) {
    13185                        // Pick a random list
    132                         unsigned i = tls.rng.next() % numLists;
     86                        int i = tls.rng.next() % numLists;
    13387
    13488                        #ifndef NO_STATS
     
    13993                        if( !lists[i].lock.try_lock() ) continue;
    14094
    141                         __attribute__((unused)) int num = numNonEmpty;
    142 
    14395                        // Actually push it
    144                         if(lists[i].push(node)) {
    145                                 numNonEmpty++;
    146                                 size_t qword = i >> 6ull;
    147                                 size_t bit   = i & 63ull;
    148                                 assertf((list_mask[qword] & (1ul << bit)) == 0, "Before set %zu:%zu (%u), %zx & %zx", qword, bit, i, list_mask[qword].load(), (1ul << bit));
    149                                 __attribute__((unused)) bool ret = bts(list_mask[qword], bit);
    150                                 assert(!ret);
    151                                 assertf((list_mask[qword] & (1ul << bit)) != 0, "After set %zu:%zu (%u), %zx & %zx", qword, bit, i, list_mask[qword].load(), (1ul << bit));
    152                         }
     96                        lists[i].push(node, numNonEmpty);
    15397                        assert(numNonEmpty <= (int)numLists);
    15498
     
    158102                        #ifndef NO_STATS
    159103                                tls.pick.push.success++;
    160                                 tls.empty.push.value += num;
    161                                 tls.empty.push.count += 1;
    162104                        #endif
    163105                        return;
     
    166108
    167109        __attribute__((noinline, hot)) node_t * pop() {
    168                 #if !defined(NO_BITMASK)
    169                         // for(int r = 0; r < 10 && numNonEmpty != 0; r++) {
    170                         //      // Pick two lists at random
    171                         //      unsigned i = tls.rng.next() % numLists;
    172                         //      unsigned j = tls.rng.next() % numLists;
    173 
    174                         //      if(auto node = try_pop(i, j)) return node;
    175                         // }
    176                         int nnempty;
    177                         while(0 != (nnempty = numNonEmpty)) {
    178                                 tls.pick.pop.mask_attempt++;
    179                                 unsigned i, j;
    180                                 // if( numLists < 4 || (numLists / nnempty) < 4 ) {
    181                                 //      // Pick two lists at random
    182                                 //      i = tls.rng.next() % numLists;
    183                                 //      j = tls.rng.next() % numLists;
    184                                 // } else
    185                                 {
    186                                         #ifndef NO_STATS
    187                                                 // tls.pick.push.mask_attempt++;
    188                                         #endif
    189 
    190                                         // Pick two lists at random
    191                                         unsigned num = ((numLists - 1) >> 6) + 1;
    192 
    193                                         unsigned ri = tls.rng.next();
    194                                         unsigned rj = tls.rng.next();
    195 
    196                                         unsigned wdxi = (ri >> 6u) % num;
    197                                         unsigned wdxj = (rj >> 6u) % num;
    198 
    199                                         size_t maski = list_mask[wdxi].load(std::memory_order_relaxed);
    200                                         size_t maskj = list_mask[wdxj].load(std::memory_order_relaxed);
    201 
    202                                         if(maski == 0 && maskj == 0) continue;
    203 
    204                                         unsigned bi = rand_bit(ri, maski);
    205                                         unsigned bj = rand_bit(rj, maskj);
    206 
    207                                         assertf(bi < 64, "%zu %u", maski, bi);
    208                                         assertf(bj < 64, "%zu %u", maskj, bj);
    209 
    210                                         i = bi | (wdxi << 6);
    211                                         j = bj | (wdxj << 6);
    212 
    213                                         assertf(i < numLists, "%u", wdxi << 6);
    214                                         assertf(j < numLists, "%u", wdxj << 6);
    215                                 }
    216 
    217                                 if(auto node = try_pop(i, j)) return node;
    218                         }
    219                 #else
    220                         while(numNonEmpty != 0) {
    221                                 // Pick two lists at random
    222                                 int i = tls.rng.next() % numLists;
    223                                 int j = tls.rng.next() % numLists;
    224 
    225                                 if(auto node = try_pop(i, j)) return node;
    226                         }
    227                 #endif
     110                while(numNonEmpty != 0) {
     111                        // Pick two lists at random
     112                        int i = tls.rng.next() % numLists;
     113                        int j = tls.rng.next() % numLists;
     114
     115                        #ifndef NO_STATS
     116                                tls.pick.pop.attempt++;
     117                        #endif
     118
     119                        // Pick the bet list
     120                        int w = i;
     121                        if( __builtin_expect(lists[j].ts() != 0, true) ) {
     122                                w = (lists[i].ts() < lists[j].ts()) ? i : j;
     123                        }
     124
     125                        auto & list = lists[w];
     126                        // If list looks empty retry
     127                        if( list.ts() == 0 ) continue;
     128
     129                        // If we can't get the lock retry
     130                        if( !list.lock.try_lock() ) continue;
     131
     132                        // If list is empty, unlock and retry
     133                        if( list.ts() == 0 ) {
     134                                list.lock.unlock();
     135                                continue;
     136                        }
     137
     138                        // Actually pop the list
     139                        auto node = list.pop(numNonEmpty);
     140                        assert(node);
     141
     142                        // Unlock and return
     143                        list.lock.unlock();
     144                        assert(numNonEmpty >= 0);
     145                        #ifndef NO_STATS
     146                                tls.pick.pop.success++;
     147                        #endif
     148                        return node;
     149                }
    228150
    229151                return nullptr;
    230152        }
    231 
    232 private:
    233         node_t * try_pop(unsigned i, unsigned j) {
    234                 #ifndef NO_STATS
    235                         tls.pick.pop.attempt++;
    236                 #endif
    237 
    238                 // Pick the bet list
    239                 int w = i;
    240                 if( __builtin_expect(lists[j].ts() != 0, true) ) {
    241                         w = (lists[i].ts() < lists[j].ts()) ? i : j;
    242                 }
    243 
    244                 auto & list = lists[w];
    245                 // If list looks empty retry
    246                 if( list.ts() == 0 ) return nullptr;
    247 
    248                 // If we can't get the lock retry
    249                 if( !list.lock.try_lock() ) return nullptr;
    250 
    251                 __attribute__((unused)) int num = numNonEmpty;
    252 
    253                 // If list is empty, unlock and retry
    254                 if( list.ts() == 0 ) {
    255                         list.lock.unlock();
    256                         return nullptr;
    257                 }
    258 
    259                 // Actually pop the list
    260                 node_t * node;
    261                 bool emptied;
    262                 std::tie(node, emptied) = list.pop();
    263                 assert(node);
    264 
    265                 if(emptied) {
    266                         numNonEmpty--;
    267                         size_t qword = w >> 6ull;
    268                         size_t bit   = w & 63ull;
    269                         assert((list_mask[qword] & (1ul << bit)) != 0);
    270                         __attribute__((unused)) bool ret = btr(list_mask[qword], bit);
    271                         assert(ret);
    272                         assert((list_mask[qword] & (1ul << bit)) == 0);
    273                 }
    274 
    275                 // Unlock and return
    276                 list.lock.unlock();
    277                 assert(numNonEmpty >= 0);
    278                 #ifndef NO_STATS
    279                         tls.pick.pop.success++;
    280                         tls.empty.pop.value += num;
    281                         tls.empty.pop.count += 1;
    282                 #endif
    283                 return node;
    284         }
    285153
    286154private:
     
    294162                struct stat {
    295163                        ssize_t diff = 0;
    296                         size_t  push = 0;
    297                         size_t  pop  = 0;
    298                         // size_t value = 0;
    299                         // size_t count = 0;
     164
     165                        static struct Dif {
     166                                ssize_t value = 0;
     167                                size_t  num   = 0;
     168                                ssize_t max   = 0;
     169                        } dif;
    300170                };
    301171
     
    308178                sentinel_t before;
    309179                sentinel_t after;
    310                 #ifndef NO_STATS
    311                         stat s;
    312                 #endif
    313 
    314 #pragma GCC diagnostic push
    315 #pragma GCC diagnostic ignored "-Winvalid-offsetof"
     180                stat s;
     181
    316182                static constexpr auto fields_offset = offsetof( node_t, _links );
    317 #pragma GCC diagnostic pop
    318183        public:
    319184                intrusive_queue_t()
     
    321186                        , after {{ head(), nullptr }}
    322187                {
    323                         /* paranoid */ assert((reinterpret_cast<uintptr_t>( head() ) + fields_offset) == reinterpret_cast<uintptr_t>(&before));
    324                         /* paranoid */ assert((reinterpret_cast<uintptr_t>( tail() ) + fields_offset) == reinterpret_cast<uintptr_t>(&after ));
    325                         /* paranoid */ assert(head()->_links.prev == nullptr);
    326                         /* paranoid */ assert(head()->_links.next == tail() );
    327                         /* paranoid */ assert(tail()->_links.next == nullptr);
    328                         /* paranoid */ assert(tail()->_links.prev == head() );
    329                         /* paranoid */ assert(sizeof(*this) == 128);
    330                         /* paranoid */ assert((intptr_t(this) % 128) == 0);
    331                 }
    332 
    333                 ~intrusive_queue_t() = default;
     188                        assert((reinterpret_cast<uintptr_t>( head() ) + fields_offset) == reinterpret_cast<uintptr_t>(&before));
     189                        assert((reinterpret_cast<uintptr_t>( tail() ) + fields_offset) == reinterpret_cast<uintptr_t>(&after ));
     190                        assert(head()->_links.prev == nullptr);
     191                        assert(head()->_links.next == tail() );
     192                        assert(tail()->_links.next == nullptr);
     193                        assert(tail()->_links.prev == head() );
     194                        assert(sizeof(*this) == 128);
     195                        assert((intptr_t(this) % 128) == 0);
     196                }
     197
     198                ~intrusive_queue_t() {
     199                        #ifndef NO_STATS
     200                                stat::dif.value+= s.diff;
     201                                stat::dif.num  ++;
     202                                stat::dif.max  = std::abs(stat::dif.max) > std::abs(s.diff) ? stat::dif.max : s.diff;
     203                        #endif
     204                }
    334205
    335206                inline node_t * head() const {
     
    349220                }
    350221
    351                 inline bool push(node_t * node) {
     222                inline void push(node_t * node, std::atomic_int & nonEmpty) {
    352223                        assert(lock);
    353224                        assert(node->_links.ts != 0);
     
    361232                        prev->_links.next = node;
    362233                        tail->_links.prev = node;
    363                         #ifndef NO_STATS
    364                                 if(enable_stats) {
    365                                         s.diff++;
    366                                         s.push++;
    367                                 }
    368                         #endif
    369234                        if(before._links.ts == 0l) {
     235                                nonEmpty += 1;
    370236                                before._links.ts = node->_links.ts;
    371                                 assert(node->_links.prev == this->head());
    372                                 return true;
    373                         }
    374                         return false;
    375                 }
    376 
    377                 inline std::pair<node_t *, bool> pop() {
     237                        }
     238                        #ifndef NO_STATS
     239                                if(enable_stats) s.diff++;
     240                        #endif
     241                }
     242
     243                inline node_t * pop(std::atomic_int & nonEmpty) {
    378244                        assert(lock);
    379245                        node_t * head = this->head();
     
    382248                        node_t * node = head->_links.next;
    383249                        node_t * next = node->_links.next;
    384                         if(node == tail) return {nullptr, false};
     250                        if(node == tail) return nullptr;
    385251
    386252                        head->_links.next = next;
    387253                        next->_links.prev = head;
    388254
    389                         #ifndef NO_STATS
    390                                 if(enable_stats) {
    391                                         s.diff--;
    392                                         s.pop ++;
    393                                 }
    394                         #endif
    395255                        if(next == tail) {
    396256                                before._links.ts = 0l;
    397                                 return {node, true};
     257                                nonEmpty -= 1;
    398258                        }
    399259                        else {
     
    401261                                before._links.ts = next->_links.ts;
    402262                                assert(before._links.ts != 0);
    403                                 return {node, false};
    404                         }
     263                        }
     264                        #ifndef NO_STATS
     265                                if(enable_stats) s.diff--;
     266                        #endif
     267                        return node;
    405268                }
    406269
     
    414277
    415278        static __attribute__((aligned(128))) thread_local struct TLS {
    416                 Random     rng = { int(rdtscl()) };
    417                 pick_stat  pick;
    418                 empty_stat empty;
     279                Random    rng = { int(rdtscl()) };
     280                pick_stat pick;
    419281        } tls;
    420282
    421 public:
    422         std::atomic_int numNonEmpty  = { 0 };  // number of non-empty lists
    423         std::atomic_size_t list_mask[7] = { {0}, {0}, {0}, {0}, {0}, {0}, {0} }; // which queues are empty
    424283private:
     284        std::atomic_int numNonEmpty; // number of non-empty lists
    425285        __attribute__((aligned(64))) std::unique_ptr<intrusive_queue_t []> lists;
    426286        const unsigned numLists;
     
    428288public:
    429289        static const constexpr size_t sizeof_queue = sizeof(intrusive_queue_t);
    430 
    431 #ifndef NO_STATS
    432         static void stats_print(std::ostream & os) {
    433                 auto it = head;
    434                 while(it) {
    435                         it->stats_print_local(os);
    436                         it = it->next;
    437                 }
    438         }
    439 
    440         static void stats_tls_tally() {
    441                 global_stats.pick.push.attempt += tls.pick.push.attempt;
    442                 global_stats.pick.push.success += tls.pick.push.success;
    443                 global_stats.pick.pop .attempt += tls.pick.pop.attempt;
    444                 global_stats.pick.pop .success += tls.pick.pop.success;
    445                 global_stats.pick.pop .mask_attempt += tls.pick.pop.mask_attempt;
    446 
    447                 global_stats.qstat.push.value += tls.empty.push.value;
    448                 global_stats.qstat.push.count += tls.empty.push.count;
    449                 global_stats.qstat.pop .value += tls.empty.pop .value;
    450                 global_stats.qstat.pop .count += tls.empty.pop .count;
    451         }
    452 
    453 private:
    454         static struct GlobalStats {
    455                 struct {
    456                         struct {
    457                                 std::atomic_size_t attempt = { 0 };
    458                                 std::atomic_size_t success = { 0 };
    459                         } push;
    460                         struct {
    461                                 std::atomic_size_t attempt = { 0 };
    462                                 std::atomic_size_t success = { 0 };
    463                                 std::atomic_size_t mask_attempt = { 0 };
    464                         } pop;
    465                 } pick;
    466                 struct {
    467                         struct {
    468                                 std::atomic_size_t value = { 0 };
    469                                 std::atomic_size_t count = { 0 };
    470                         } push;
    471                         struct {
    472                                 std::atomic_size_t value = { 0 };
    473                                 std::atomic_size_t count = { 0 };
    474                         } pop;
    475                 } qstat;
    476         } global_stats;
    477 
    478         // Link list of all lists for stats
    479         __attribute__((aligned(64))) relaxed_list<node_t> * next = nullptr;
    480 
    481         static relaxed_list<node_t> * head;
    482 
    483         void stats_print_local(std::ostream & os ) {
    484                 std::cout << "----- Relaxed List Stats -----" << std::endl;
    485                 {
    486                         ssize_t diff = 0;
    487                         size_t  num  = 0;
    488                         ssize_t max  = 0;
    489 
    490                         for(size_t i = 0; i < numLists; i++) {
    491                                 const auto & list = lists[i];
    492                                 diff+= list.s.diff;
    493                                 num ++;
    494                                 max  = std::abs(max) > std::abs(list.s.diff) ? max : list.s.diff;
    495                                 os << "Local Q ops   : " << (list.s.push + list.s.pop) << "(" << list.s.push << "i, " << list.s.pop << "o)\n";
    496                         }
    497 
    498                         os << "Difference   : " << ssize_t(double(diff) / num  ) << " avg\t" << max << "max" << std::endl;
    499                 }
    500 
    501                 const auto & global = global_stats;
    502 
    503                 double push_sur = (100.0 * double(global.pick.push.success) / global.pick.push.attempt);
    504                 double pop_sur  = (100.0 * double(global.pick.pop .success) / global.pick.pop .attempt);
    505                 double mpop_sur = (100.0 * double(global.pick.pop .success) / global.pick.pop .mask_attempt);
    506 
    507                 os << "Push   Pick % : " << push_sur << "(" << global.pick.push.success << " / " << global.pick.push.attempt << ")\n";
    508                 os << "Pop    Pick % : " << pop_sur  << "(" << global.pick.pop .success << " / " << global.pick.pop .attempt << ")\n";
    509                 os << "TryPop Pick % : " << mpop_sur << "(" << global.pick.pop .success << " / " << global.pick.pop .mask_attempt << ")\n";
    510 
    511                 double avgQ_push = double(global.qstat.push.value) / global.qstat.push.count;
    512                 double avgQ_pop  = double(global.qstat.pop .value) / global.qstat.pop .count;
    513                 double avgQ      = double(global.qstat.push.value + global.qstat.pop .value) / (global.qstat.push.count + global.qstat.pop .count);
    514                 os << "Push   Avg Qs : " << avgQ_push << " (" << global.qstat.push.count << "ops)\n";
    515                 os << "Pop    Avg Qs : " << avgQ_pop  << " (" << global.qstat.pop .count << "ops)\n";
    516                 os << "Global Avg Qs : " << avgQ      << " (" << (global.qstat.push.count + global.qstat.pop .count) << "ops)\n";
    517         }
    518 #endif
    519 };
     290};
  • doc/theses/thierry_delisle_PhD/code/utils.hpp

    ra505021 r8c50aed  
    1010#include <unistd.h>
    1111#include <sys/sysinfo.h>
    12 
    13 #include <x86intrin.h>
    1412
    1513// Barrier from
     
    5856}
    5957
    60 static inline void affinity(int tid) {
     58void affinity(int tid) {
    6159        static int cpus = get_nprocs();
    6260
     
    7270
    7371static const constexpr std::size_t cache_line_size = 64;
    74 static inline void check_cache_line_size() {
     72void check_cache_line_size() {
    7573        std::cout << "Checking cache line size" << std::endl;
    7674        const std::string cache_file = "/sys/devices/system/cpu/cpu0/cache/index0/coherency_line_size";
     
    105103        return std::chrono::duration_cast<std::chrono::duration<T, Ratio>>(std::chrono::duration<T>(seconds)).count();
    106104}
    107 
    108 static inline unsigned rand_bit(unsigned rnum, size_t mask) {
    109         unsigned bit = mask ? rnum % __builtin_popcountl(mask) : 0;
    110 #if !defined(__BMI2__)
    111         uint64_t v = mask;   // Input value to find position with rank r.
    112         unsigned int r = bit + 1;// Input: bit's desired rank [1-64].
    113         unsigned int s;      // Output: Resulting position of bit with rank r [1-64]
    114         uint64_t a, b, c, d; // Intermediate temporaries for bit count.
    115         unsigned int t;      // Bit count temporary.
    116 
    117         // Do a normal parallel bit count for a 64-bit integer,
    118         // but store all intermediate steps.
    119         a =  v - ((v >> 1) & ~0UL/3);
    120         b = (a & ~0UL/5) + ((a >> 2) & ~0UL/5);
    121         c = (b + (b >> 4)) & ~0UL/0x11;
    122         d = (c + (c >> 8)) & ~0UL/0x101;
    123 
    124 
    125         t = (d >> 32) + (d >> 48);
    126         // Now do branchless select!
    127         s  = 64;
    128         s -= ((t - r) & 256) >> 3; r -= (t & ((t - r) >> 8));
    129         t  = (d >> (s - 16)) & 0xff;
    130         s -= ((t - r) & 256) >> 4; r -= (t & ((t - r) >> 8));
    131         t  = (c >> (s - 8)) & 0xf;
    132         s -= ((t - r) & 256) >> 5; r -= (t & ((t - r) >> 8));
    133         t  = (b >> (s - 4)) & 0x7;
    134         s -= ((t - r) & 256) >> 6; r -= (t & ((t - r) >> 8));
    135         t  = (a >> (s - 2)) & 0x3;
    136         s -= ((t - r) & 256) >> 7; r -= (t & ((t - r) >> 8));
    137         t  = (v >> (s - 1)) & 0x1;
    138         s -= ((t - r) & 256) >> 8;
    139         return s - 1;
    140 #else
    141         uint64_t picked = _pdep_u64(1ul << bit, mask);
    142         return picked ? __builtin_ctzl(picked) : 0;
    143 #endif
    144 }
  • driver/cfa.cc

    ra505021 r8c50aed  
    411411                args[nargs++] = "-lcfathread";
    412412                args[nargs++] = "-Wl,--pop-state";
    413                 args[nargs++] = "-Wl,--push-state,--no-as-needed";
    414413                args[nargs++] = "-lcfa";
    415                 args[nargs++] = "-Wl,--pop-state";
    416414                args[nargs++] = "-pthread";
    417415                args[nargs++] = "-ldl";
  • libcfa/prelude/Makefile.am

    ra505021 r8c50aed  
    1111## Created On       : Sun May 31 08:54:01 2015
    1212## Last Modified By : Peter A. Buhr
    13 ## Last Modified On : Mon Feb  3 21:27:18 2020
    14 ## Update Count     : 208
     13## Last Modified On : Wed Dec 14 15:00:35 2016
     14## Update Count     : 205
    1515###############################################################################
    1616
     
    3636extras.cf : ${srcdir}/extras.regx ${srcdir}/extras.c
    3737        ${AM_V_GEN}gcc ${AM_CFLAGS} -E ${srcdir}/extras.c | grep -f ${srcdir}/extras.regx > extras.cf
    38         ${AM_V_GEN}gcc ${AM_CFLAGS} -E ${srcdir}/extras.c | grep -zo -f ${srcdir}/extras.regx2 | tr '\0' '\n' >> extras.cf
    3938
    4039# create forward declarations for gcc builtins
  • libcfa/prelude/Makefile.in

    ra505021 r8c50aed  
    1 # Makefile.in generated by automake 1.16.1 from Makefile.am.
     1# Makefile.in generated by automake 1.15 from Makefile.am.
    22# @configure_input@
    33
    4 # Copyright (C) 1994-2018 Free Software Foundation, Inc.
     4# Copyright (C) 1994-2014 Free Software Foundation, Inc.
    55
    66# This Makefile.in is free software; the Free Software Foundation
     
    331331            cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
    332332          *) \
    333             echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
    334             cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
     333            echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
     334            cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
    335335        esac;
    336336
     
    377377
    378378
    379 distdir: $(BUILT_SOURCES)
    380         $(MAKE) $(AM_MAKEFLAGS) distdir-am
    381 
    382 distdir-am: $(DISTFILES)
     379distdir: $(DISTFILES)
    383380        @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
    384381        topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
     
    543540extras.cf : ${srcdir}/extras.regx ${srcdir}/extras.c
    544541        ${AM_V_GEN}gcc ${AM_CFLAGS} -E ${srcdir}/extras.c | grep -f ${srcdir}/extras.regx > extras.cf
    545         ${AM_V_GEN}gcc ${AM_CFLAGS} -E ${srcdir}/extras.c | grep -zo -f ${srcdir}/extras.regx2 | tr '\0' '\n' >> extras.cf
    546542
    547543# create forward declarations for gcc builtins
  • libcfa/prelude/extras.regx

    ra505021 r8c50aed  
    2424typedef.* char32_t;
    2525typedef.* wchar_t;
     26extern.*\*malloc\(.*\).*
     27extern.* free\(.*\).*
     28extern.* exit\(.*\).*
     29extern.* atexit\(.*\).*
     30extern.* abort\(.*\).*
     31extern.* printf\(.*\).*
  • libcfa/prelude/prototypes.awk

    ra505021 r8c50aed  
    1010# Created On       : Sat May 16 07:57:37 2015
    1111# Last Modified By : Peter A. Buhr
    12 # Last Modified On : Sat Feb  8 09:46:58 2020
    13 # Update Count     : 36
     12# Last Modified On : Thu Jun  6 20:46:28 2019
     13# Update Count     : 34
    1414#
    1515
     
    1717
    1818BEGIN {
    19         FS = "[( )]"
     19  FS = "[( )]"
    2020        # order so string search is longest string
    2121        i=-1
     
    8484
    8585/BT_FN/ {
    86         for (i = 1; i <= NF; i += 1 ) {
    87                 if ( match($i, "BT_FN") != 0 ) {
    88                         prototypes[$i] = $i
    89                 }
     86        for (i = 1; i <= NF; i++) {
     87          if( match($i, "BT_FN") != 0 ) {
     88                prototypes[$i] = $i
     89          }
    9090        }
    91 }
     91  }
    9292
    9393END {
     
    103103
    104104        for ( prototype in prototypes ) {
    105                 # printf( "//\"%s\"\n", prototype )
    106                 if ( index( "BT_LAST", prototype ) == 1 ) {
    107                         continue
     105          # printf( "//\"%s\"\n", prototype )
     106          if ( index( "BT_LAST", prototype ) == 1 ) {
     107                continue
     108          } # if
     109
     110          printf( "#define %s(NAME) FUNC_SIMPLE(", prototype )
     111
     112          if ( sub( "BT_FN_", "", prototype ) == 0 ) {
     113                printf( "\n********** BAD MACRO NAME \"%s\" **********\n", prototype )
     114                exit 0
     115          } # if
     116
     117          # generate function return type as macro
     118          for ( t = 0; t < N; t += 1 ) {                                        # find longest match
     119                type = types[t];
     120                if ( index( prototype, type ) == 1 ) {          # found match
     121                  printf( "BT_%s, NAME", type )
     122                  sub( type, "", prototype )
     123                  break;
    108124                } # if
     125          } # for
    109126
    110                 printf( "#define %s(NAME) FUNC_SIMPLE(", prototype )
    111 
    112                 if ( sub( "BT_FN_", "", prototype ) == 0 ) {
    113                         printf( "\n********** BAD MACRO NAME \"%s\" **********\n", prototype )
     127          # generate function parameter types as macro
     128          if ( index( prototype, "VAR" ) != 2 ) {                       # C-style empty parameters ?
     129                for ( p = 0; length( prototype ) > 0; p += 1 ) { # until all parameters types are removed
     130                  sub( "_", "", prototype)                              # remove "_"
     131                  printf( ", ", type )
     132                  temp = prototype
     133                  for ( t = 0; t < N; t += 1 ) {                        # find longest match
     134                        type = types[t];
     135                        if ( index( prototype, type ) == 1 ) { # found match
     136                          printf( "BT_%s", type )
     137                          sub( type, "", prototype )
     138                          break;
     139                        } # if
     140                  } # for
     141                  if ( temp == prototype ) {                            # no match found for parameter in macro table
     142                        printf( "\n********** MISSING TYPE \"%s\" **********\n", prototype )
    114143                        exit 0
    115                 } # if
    116 
    117                 # generate function return type as macro
    118                 for ( t = 0; t < N; t += 1 ) {                                  # find longest match
    119                         type = types[t];
    120                         if ( index( prototype, type ) == 1 ) {          # found match
    121                                 printf( "BT_%s, NAME", type )
    122                                 sub( type, "", prototype )
    123                                 break;
    124                         } # if
     144                  } # if
    125145                } # for
    126 
    127                 # generate function parameter types as macro
    128                 if ( index( prototype, "VAR" ) != 2 ) {                 # C-style empty parameters ?
    129                         for ( p = 0; length( prototype ) > 0; p += 1 ) { # until all parameters types are removed
    130                                 sub( "_", "", prototype)                                # remove "_"
    131                                 printf( ", ", type )
    132                                 temp = prototype
    133                                 for ( t = 0; t < N; t += 1 ) {                  # find longest match
    134                                         type = types[t];
    135                                         if ( index( prototype, type ) == 1 ) { # found match
    136                                                 printf( "BT_%s", type )
    137                                                 sub( type, "", prototype )
    138                                                 break;
    139                                         } # if
    140                                 } # for
    141                                 if ( temp == prototype ) {                              # no match found for parameter in macro table
    142                                         printf( "\n********** MISSING TYPE \"%s\" **********\n", prototype )
    143                                         exit 0
    144                                 } # if
    145                         } # for
    146                 } # if
    147                 printf( ")\n" )
     146          } # if
     147          printf( ")\n" )
    148148        } # for
    149149
  • libcfa/src/assert.cfa

    ra505021 r8c50aed  
    1010// Created On       : Mon Nov 28 12:27:26 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Feb  4 13:00:18 2020
    13 // Update Count     : 6
     12// Last Modified On : Thu Nov 21 17:09:26 2019
     13// Update Count     : 5
    1414//
    1515
     
    2626
    2727        // called by macro assert in assert.h
    28         void __assert_fail( const char assertion[], const char file[], unsigned int line, const char function[] ) {
     28        void __assert_fail( const char *assertion, const char *file, unsigned int line, const char *function ) {
    2929                __cfaabi_bits_print_safe( STDERR_FILENO, CFA_ASSERT_FMT ".\n", assertion, __progname, function, line, file );
    3030                abort();
     
    3232
    3333        // called by macro assertf
    34         void __assert_fail_f( const char assertion[], const char file[], unsigned int line, const char function[], const char fmt[], ... ) {
     34        void __assert_fail_f( const char *assertion, const char *file, unsigned int line, const char *function, const char *fmt, ... ) {
    3535                __cfaabi_bits_acquire();
    3636                __cfaabi_bits_print_nolock( STDERR_FILENO, CFA_ASSERT_FMT ": ", assertion, __progname, function, line, file );
  • libcfa/src/bits/debug.cfa

    ra505021 r8c50aed  
    1010// Created On       : Thu Mar 30 12:30:01 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Feb  4 13:03:16 2020
    13 // Update Count     : 11
     12// Last Modified On : Thu Nov 21 17:16:30 2019
     13// Update Count     : 10
    1414//
    1515
     
    2727
    2828extern "C" {
    29         void __cfaabi_bits_write( int fd, const char in_buffer[], int len ) {
     29
     30        void __cfaabi_bits_write( int fd, const char *in_buffer, int len ) {
    3031                // ensure all data is written
    3132                for ( int count = 0, retcode; count < len; count += retcode ) {
  • libcfa/src/bits/debug.hfa

    ra505021 r8c50aed  
    1010// Created On       : Mon Nov 28 12:27:26 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Feb  4 12:29:21 2020
    13 // Update Count     : 9
     12// Last Modified On : Thu Nov 21 17:06:58 2019
     13// Update Count     : 8
    1414//
    1515
     
    2121        #define __cfaabi_dbg_ctx __PRETTY_FUNCTION__
    2222        #define __cfaabi_dbg_ctx2 , __PRETTY_FUNCTION__
    23         #define __cfaabi_dbg_ctx_param const char caller[]
    24         #define __cfaabi_dbg_ctx_param2 , const char caller[]
     23        #define __cfaabi_dbg_ctx_param const char * caller
     24        #define __cfaabi_dbg_ctx_param2 , const char * caller
    2525#else
    2626        #define __cfaabi_dbg_debug_do(...)
     
    3838        #include <stdio.h>
    3939
    40         extern void __cfaabi_bits_write( int fd, const char buffer[], int len );
     40        extern void __cfaabi_bits_write( int fd, const char *buffer, int len );
    4141        extern void __cfaabi_bits_acquire();
    4242        extern void __cfaabi_bits_release();
  • libcfa/src/bits/locks.hfa

    ra505021 r8c50aed  
    1010// Created On       : Tue Oct 31 15:14:38 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Feb  4 13:03:19 2020
    13 // Update Count     : 11
     12// Last Modified On : Sat Aug 11 15:42:24 2018
     13// Update Count     : 10
    1414//
    1515
     
    5454
    5555                #ifdef __CFA_DEBUG__
    56                         void __cfaabi_dbg_record(__spinlock_t & this, const char prev_name[]);
     56                        void __cfaabi_dbg_record(__spinlock_t & this, const char * prev_name);
    5757                #else
    5858                        #define __cfaabi_dbg_record(x, y)
  • libcfa/src/concurrency/coroutine.cfa

    ra505021 r8c50aed  
    1010// Created On       : Mon Nov 28 12:27:26 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Feb  4 12:29:25 2020
    13 // Update Count     : 16
     12// Last Modified On : Thu Dec  5 14:37:29 2019
     13// Update Count     : 15
    1414//
    1515
     
    8989}
    9090
    91 void ?{}( coroutine_desc & this, const char name[], void * storage, size_t storageSize ) with( this ) {
     91void ?{}( coroutine_desc & this, const char * name, void * storage, size_t storageSize ) with( this ) {
    9292        (this.context){0p, 0p};
    9393        (this.stack){storage, storageSize};
  • libcfa/src/concurrency/coroutine.hfa

    ra505021 r8c50aed  
    1010// Created On       : Mon Nov 28 12:27:26 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Feb  4 12:29:26 2020
    13 // Update Count     : 11
     12// Last Modified On : Tue Dec  3 22:47:58 2019
     13// Update Count     : 10
    1414//
    1515
     
    3535// void ^?{}( coStack_t & this );
    3636
    37 void ?{}( coroutine_desc & this, const char name[], void * storage, size_t storageSize );
     37void ?{}( coroutine_desc & this, const char * name, void * storage, size_t storageSize );
    3838void ^?{}( coroutine_desc & this );
    3939
     
    4141static inline void ?{}( coroutine_desc & this, size_t stackSize)                     { this{ "Anonymous Coroutine", 0p, stackSize }; }
    4242static inline void ?{}( coroutine_desc & this, void * storage, size_t storageSize )  { this{ "Anonymous Coroutine", storage, storageSize }; }
    43 static inline void ?{}( coroutine_desc & this, const char name[])                    { this{ name, 0p, 0 }; }
    44 static inline void ?{}( coroutine_desc & this, const char name[], size_t stackSize ) { this{ name, 0p, stackSize }; }
     43static inline void ?{}( coroutine_desc & this, const char * name)                    { this{ name, 0p, 0 }; }
     44static inline void ?{}( coroutine_desc & this, const char * name, size_t stackSize ) { this{ name, 0p, stackSize }; }
    4545
    4646//-----------------------------------------------------------------------------
  • libcfa/src/concurrency/kernel.cfa

    ra505021 r8c50aed  
    1010// Created On       : Tue Jan 17 12:27:26 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Feb  4 13:03:15 2020
    13 // Update Count     : 58
     12// Last Modified On : Thu Jan 30 22:55:50 2020
     13// Update Count     : 56
    1414//
    1515
     
    210210static void * CtxInvokeProcessor(void * arg);
    211211
    212 void ?{}(processor & this, const char name[], cluster & cltr) with( this ) {
     212void ?{}(processor & this, const char * name, cluster & cltr) with( this ) {
    213213        this.name = name;
    214214        this.cltr = &cltr;
     
    244244}
    245245
    246 void ?{}(cluster & this, const char name[], Duration preemption_rate) with( this ) {
     246void ?{}(cluster & this, const char * name, Duration preemption_rate) with( this ) {
    247247        this.name = name;
    248248        this.preemption_rate = preemption_rate;
     
    459459}
    460460
    461 static void Abort( int ret, const char func[] ) {
     461static void Abort( int ret, const char * func ) {
    462462        if ( ret ) {                                                                            // pthread routines return errno values
    463463                abort( "%s : internal error, error(%d) %s.", func, ret, strerror( ret ) );
     
    960960__cfaabi_dbg_debug_do(
    961961        extern "C" {
    962                 void __cfaabi_dbg_record(__spinlock_t & this, const char prev_name[]) {
     962                void __cfaabi_dbg_record(__spinlock_t & this, const char * prev_name) {
    963963                        this.prev_name = prev_name;
    964964                        this.prev_thrd = kernelTLS.this_thread;
  • libcfa/src/concurrency/kernel.hfa

    ra505021 r8c50aed  
    1010// Created On       : Tue Jan 17 12:27:26 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Feb  4 12:29:26 2020
    13 // Update Count     : 22
     12// Last Modified On : Wed Dec  4 07:54:51 2019
     13// Update Count     : 18
    1414//
    1515
     
    101101};
    102102
    103 void  ?{}(processor & this, const char name[], struct cluster & cltr);
     103void  ?{}(processor & this, const char * name, struct cluster & cltr);
    104104void ^?{}(processor & this);
    105105
    106106static inline void  ?{}(processor & this)                    { this{ "Anonymous Processor", *mainCluster}; }
    107107static inline void  ?{}(processor & this, struct cluster & cltr)    { this{ "Anonymous Processor", cltr}; }
    108 static inline void  ?{}(processor & this, const char name[]) { this{name, *mainCluster }; }
     108static inline void  ?{}(processor & this, const char * name) { this{name, *mainCluster }; }
    109109
    110110static inline [processor *&, processor *& ] __get( processor & this ) /*__attribute__((const))*/ { return this.node.[next, prev]; }
     
    144144extern Duration default_preemption();
    145145
    146 void ?{} (cluster & this, const char name[], Duration preemption_rate);
     146void ?{} (cluster & this, const char * name, Duration preemption_rate);
    147147void ^?{}(cluster & this);
    148148
    149149static inline void ?{} (cluster & this)                           { this{"Anonymous Cluster", default_preemption()}; }
    150150static inline void ?{} (cluster & this, Duration preemption_rate) { this{"Anonymous Cluster", preemption_rate}; }
    151 static inline void ?{} (cluster & this, const char name[])        { this{name, default_preemption()}; }
     151static inline void ?{} (cluster & this, const char * name)        { this{name, default_preemption()}; }
    152152
    153153static inline [cluster *&, cluster *& ] __get( cluster & this ) /*__attribute__((const))*/ { return this.node.[next, prev]; }
  • libcfa/src/exception.c

    ra505021 r8c50aed  
    248248}
    249249
    250 #pragma GCC push_options
    251 #pragma GCC optimize("O0")
    252 
     250#if defined(PIC)
     251#warning Exceptions not yet supported when using Position-Independent Code
     252__attribute__((noinline))
     253void __cfaabi_ehm__try_terminate(void (*try_block)(),
     254                void (*catch_block)(int index, exception_t * except),
     255                __attribute__((unused)) int (*match_block)(exception_t * except)) {
     256        abort();
     257}
     258#else // PIC
    253259// This is our personality routine. For every stack frame annotated with
    254260// ".cfi_personality 0x3,__gcfa_personality_v0" this function will be called twice when unwinding.
     
    425431
    426432        // Setup the personality routine and exception table.
    427 #ifdef __PIC__
    428         asm volatile (".cfi_personality 0x9b,CFA.ref.__gcfa_personality_v0");
    429         asm volatile (".cfi_lsda 0x1b, .LLSDACFA2");
    430 #else
    431433        asm volatile (".cfi_personality 0x3,__gcfa_personality_v0");
    432434        asm volatile (".cfi_lsda 0x3, .LLSDACFA2");
    433 #endif
    434435
    435436        // Label which defines the start of the area for which the handler is setup.
     
    463464// have a single call to the try routine.
    464465
    465 #ifdef __PIC__
    466 #if defined( __i386 ) || defined( __x86_64 )
    467 asm (
    468         // HEADER
    469         ".LFECFA1:\n"
    470         "       .globl  __gcfa_personality_v0\n"
    471         "       .section        .gcc_except_table,\"a\",@progbits\n"
    472         // TABLE HEADER (important field is the BODY length at the end)
    473         ".LLSDACFA2:\n"
    474         "       .byte   0xff\n"
    475         "       .byte   0xff\n"
    476         "       .byte   0x1\n"
    477         "       .uleb128 .LLSDACSECFA2-.LLSDACSBCFA2\n"
    478         // BODY (language specific data)
    479         // This uses language specific data and can be modified arbitrarily
    480         // We use handled area offset, handled area length,
    481         // handler landing pad offset and 1 (action code, gcc seems to use 0).
    482         ".LLSDACSBCFA2:\n"
    483         "       .uleb128 .TRYSTART-__cfaabi_ehm__try_terminate\n"
    484         "       .uleb128 .TRYEND-.TRYSTART\n"
    485         "       .uleb128 .CATCH-__cfaabi_ehm__try_terminate\n"
    486         "       .uleb128 1\n"
    487         ".LLSDACSECFA2:\n"
    488         // TABLE FOOTER
    489         "       .text\n"
    490         "       .size   __cfaabi_ehm__try_terminate, .-__cfaabi_ehm__try_terminate\n"
    491 );
    492 
    493 // Somehow this piece of helps with the resolution of debug symbols.
    494 __attribute__((unused)) static const int dummy = 0;
    495 
    496 asm (
    497         // Add a hidden symbol which points at the function.
    498         "       .hidden CFA.ref.__gcfa_personality_v0\n"
    499         "       .weak   CFA.ref.__gcfa_personality_v0\n"
    500         // No clue what this does specifically
    501         "       .section        .data.rel.local.CFA.ref.__gcfa_personality_v0,\"awG\",@progbits,CFA.ref.__gcfa_personality_v0,comdat\n"
    502         "       .align 8\n"
    503         "       .type CFA.ref.__gcfa_personality_v0, @object\n"
    504         "       .size CFA.ref.__gcfa_personality_v0, 8\n"
    505         "CFA.ref.__gcfa_personality_v0:\n"
    506 #if defined( __x86_64 )
    507         "       .quad __gcfa_personality_v0\n"
    508 #else // then __i386
    509         "   .long __gcfa_personality_v0\n"
    510 #endif
    511 );
    512 #else
    513 #error Exception Handling: unknown architecture for position independent code.
    514 #endif // __i386 || __x86_64
    515 #else // __PIC__
    516466#if defined( __i386 ) || defined( __x86_64 )
    517467asm (
     
    541491        "       .size   __cfaabi_ehm__try_terminate, .-__cfaabi_ehm__try_terminate\n"
    542492        "       .ident  \"GCC: (Ubuntu 6.2.0-3ubuntu11~16.04) 6.2.0 20160901\"\n"
    543         "       .section        .note.GNU-stack,\"x\",@progbits\n"
     493//      "       .section        .note.GNU-stack,\"x\",@progbits\n"
    544494);
    545 #else
    546 #error Exception Handling: unknown architecture for position dependent code.
    547495#endif // __i386 || __x86_64
    548 #endif // __PIC__
    549 
    550 #pragma GCC pop_options
     496#endif // PIC
  • libcfa/src/fstream.cfa

    ra505021 r8c50aed  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Feb  7 19:01:01 2020
    13 // Update Count     : 363
     12// Last Modified On : Fri Nov 29 06:56:46 2019
     13// Update Count     : 355
    1414//
    1515
     
    3232
    3333void ?{}( ofstream & os, void * file ) {
    34         os.$file = file;
    35         os.$sepDefault = true;
    36         os.$sepOnOff = false;
    37         os.$nlOnOff = true;
    38         os.$prt = false;
    39         os.$sawNL = false;
    40         $sepSetCur( os, sepGet( os ) );
     34        os.file = file;
     35        os.sepDefault = true;
     36        os.sepOnOff = false;
     37        os.nlOnOff = true;
     38        os.prt = false;
     39        os.sawNL = false;
    4140        sepSet( os, " " );
     41        sepSetCur( os, sepGet( os ) );
    4242        sepSetTuple( os, ", " );
    4343} // ?{}
    4444
    4545// private
    46 bool $sepPrt( ofstream & os ) { $setNL( os, false ); return os.$sepOnOff; }
    47 void $sepReset( ofstream & os ) { os.$sepOnOff = os.$sepDefault; }
    48 void $sepReset( ofstream & os, bool reset ) { os.$sepDefault = reset; os.$sepOnOff = os.$sepDefault; }
    49 const char * $sepGetCur( ofstream & os ) { return os.$sepCur; }
    50 void $sepSetCur( ofstream & os, const char sepCur[] ) { os.$sepCur = sepCur; }
    51 bool $getNL( ofstream & os ) { return os.$sawNL; }
    52 void $setNL( ofstream & os, bool state ) { os.$sawNL = state; }
    53 bool $getANL( ofstream & os ) { return os.$nlOnOff; }
    54 bool $getPrt( ofstream & os ) { return os.$prt; }
    55 void $setPrt( ofstream & os, bool state ) { os.$prt = state; }
     46bool sepPrt( ofstream & os ) { setNL( os, false ); return os.sepOnOff; }
     47void sepReset( ofstream & os ) { os.sepOnOff = os.sepDefault; }
     48void sepReset( ofstream & os, bool reset ) { os.sepDefault = reset; os.sepOnOff = os.sepDefault; }
     49const char * sepGetCur( ofstream & os ) { return os.sepCur; }
     50void sepSetCur( ofstream & os, const char * sepCur ) { os.sepCur = sepCur; }
     51bool getNL( ofstream & os ) { return os.sawNL; }
     52void setNL( ofstream & os, bool state ) { os.sawNL = state; }
     53bool getANL( ofstream & os ) { return os.nlOnOff; }
     54bool getPrt( ofstream & os ) { return os.prt; }
     55void setPrt( ofstream & os, bool state ) { os.prt = state; }
    5656
    5757// public
    58 void ?{}( ofstream & os ) { os.$file = 0p; }
    59 
    60 void ?{}( ofstream & os, const char name[], const char mode[] ) {
     58void ?{}( ofstream & os ) { os.file = 0; }
     59
     60void ?{}( ofstream & os, const char * name, const char * mode ) {
    6161        open( os, name, mode );
    6262} // ?{}
    6363
    64 void ?{}( ofstream & os, const char name[] ) {
     64void ?{}( ofstream & os, const char * name ) {
    6565        open( os, name, "w" );
    6666} // ?{}
     
    7070} // ^?{}
    7171
    72 void sepOn( ofstream & os ) { os.$sepOnOff = ! $getNL( os ); }
    73 void sepOff( ofstream & os ) { os.$sepOnOff = false; }
     72void sepOn( ofstream & os ) { os.sepOnOff = ! getNL( os ); }
     73void sepOff( ofstream & os ) { os.sepOnOff = false; }
    7474
    7575bool sepDisable( ofstream & os ) {
    76         bool temp = os.$sepDefault;
    77         os.$sepDefault = false;
    78         $sepReset( os );
     76        bool temp = os.sepDefault;
     77        os.sepDefault = false;
     78        sepReset( os );
    7979        return temp;
    8080} // sepDisable
    8181
    8282bool sepEnable( ofstream & os ) {
    83         bool temp = os.$sepDefault;
    84         os.$sepDefault = true;
    85         if ( os.$sepOnOff ) $sepReset( os );                            // start of line ?
     83        bool temp = os.sepDefault;
     84        os.sepDefault = true;
     85        if ( os.sepOnOff ) sepReset( os );                                      // start of line ?
    8686        return temp;
    8787} // sepEnable
    8888
    89 void nlOn( ofstream & os ) { os.$nlOnOff = true; }
    90 void nlOff( ofstream & os ) { os.$nlOnOff = false; }
    91 
    92 const char * sepGet( ofstream & os ) { return os.$separator; }
    93 void sepSet( ofstream & os, const char s[] ) {
     89void nlOn( ofstream & os ) { os.nlOnOff = true; }
     90void nlOff( ofstream & os ) { os.nlOnOff = false; }
     91
     92const char * sepGet( ofstream & os ) { return os.separator; }
     93void sepSet( ofstream & os, const char * s ) {
    9494        assert( s );
    95         strncpy( os.$separator, s, sepSize - 1 );
    96         os.$separator[sepSize - 1] = '\0';
     95        strncpy( os.separator, s, sepSize - 1 );
     96        os.separator[sepSize - 1] = '\0';
    9797} // sepSet
    9898
    99 const char * sepGetTuple( ofstream & os ) { return os.$tupleSeparator; }
    100 void sepSetTuple( ofstream & os, const char s[] ) {
     99const char * sepGetTuple( ofstream & os ) { return os.tupleSeparator; }
     100void sepSetTuple( ofstream & os, const char * s ) {
    101101        assert( s );
    102         strncpy( os.$tupleSeparator, s, sepSize - 1 );
    103         os.$tupleSeparator[sepSize - 1] = '\0';
     102        strncpy( os.tupleSeparator, s, sepSize - 1 );
     103        os.tupleSeparator[sepSize - 1] = '\0';
    104104} // sepSet
    105105
    106106void ends( ofstream & os ) {
    107         if ( $getANL( os ) ) nl( os );
    108         else $setPrt( os, false );                                                      // turn off
     107        if ( getANL( os ) ) nl( os );
     108        else setPrt( os, false );                                                       // turn off
    109109        if ( &os == &exit ) exit( EXIT_FAILURE );
    110110        if ( &os == &abort ) abort();
     
    112112
    113113int fail( ofstream & os ) {
    114         return os.$file == 0 || ferror( (FILE *)(os.$file) );
     114        return os.file == 0 || ferror( (FILE *)(os.file) );
    115115} // fail
    116116
    117117int flush( ofstream & os ) {
    118         return fflush( (FILE *)(os.$file) );
     118        return fflush( (FILE *)(os.file) );
    119119} // flush
    120120
    121 void open( ofstream & os, const char name[], const char mode[] ) {
     121void open( ofstream & os, const char * name, const char * mode ) {
    122122        FILE * file = fopen( name, mode );
    123123        #ifdef __CFA_DEBUG__
    124         if ( file == 0p ) {
     124        if ( file == 0 ) {
    125125                abort | IO_MSG "open output file \"" | name | "\"" | nl | strerror( errno );
    126126        } // if
     
    129129} // open
    130130
    131 void open( ofstream & os, const char name[] ) {
     131void open( ofstream & os, const char * name ) {
    132132        open( os, name, "w" );
    133133} // open
    134134
    135135void close( ofstream & os ) {
    136         if ( (FILE *)(os.$file) == stdout || (FILE *)(os.$file) == stderr ) return;
    137 
    138         if ( fclose( (FILE *)(os.$file) ) == EOF ) {
     136        if ( (FILE *)(os.file) == stdout || (FILE *)(os.file) == stderr ) return;
     137
     138        if ( fclose( (FILE *)(os.file) ) == EOF ) {
    139139                abort | IO_MSG "close output" | nl | strerror( errno );
    140140        } // if
    141141} // close
    142142
    143 ofstream & write( ofstream & os, const char data[], size_t size ) {
     143ofstream & write( ofstream & os, const char * data, size_t size ) {
    144144        if ( fail( os ) ) {
    145145                abort | IO_MSG "attempt write I/O on failed stream";
    146146        } // if
    147147
    148         if ( fwrite( data, 1, size, (FILE *)(os.$file) ) != size ) {
     148        if ( fwrite( data, 1, size, (FILE *)(os.file) ) != size ) {
    149149                abort | IO_MSG "write" | nl | strerror( errno );
    150150        } // if
     
    155155        va_list args;
    156156        va_start( args, format );
    157         int len = vfprintf( (FILE *)(os.$file), format, args );
     157        int len = vfprintf( (FILE *)(os.file), format, args );
    158158        if ( len == EOF ) {
    159                 if ( ferror( (FILE *)(os.$file) ) ) {
     159                if ( ferror( (FILE *)(os.file) ) ) {
    160160                        abort | IO_MSG "invalid write";
    161161                } // if
     
    163163        va_end( args );
    164164
    165         $setPrt( os, true );                                                            // called in output cascade
    166         $sepReset( os );                                                                        // reset separator
     165        setPrt( os, true );                                                                     // called in output cascade
     166        sepReset( os );                                                                         // reset separator
    167167        return len;
    168168} // fmt
     
    184184// private
    185185void ?{}( ifstream & is, void * file ) {
    186         is.$file = file;
    187         is.$nlOnOff = false;
     186        is.file = file;
     187        is.nlOnOff = false;
    188188} // ?{}
    189189
    190190// public
    191 void ?{}( ifstream & is ) { is.$file = 0p; }
    192 
    193 void ?{}( ifstream & is, const char name[], const char mode[] ) {
     191void ?{}( ifstream & is ) {     is.file = 0; }
     192
     193void ?{}( ifstream & is, const char * name, const char * mode ) {
    194194        open( is, name, mode );
    195195} // ?{}
    196196
    197 void ?{}( ifstream & is, const char name[] ) {
     197void ?{}( ifstream & is, const char * name ) {
    198198        open( is, name, "r" );
    199199} // ?{}
     
    203203} // ^?{}
    204204
    205 void nlOn( ifstream & os ) { os.$nlOnOff = true; }
    206 void nlOff( ifstream & os ) { os.$nlOnOff = false; }
    207 bool getANL( ifstream & os ) { return os.$nlOnOff; }
     205void nlOn( ifstream & os ) { os.nlOnOff = true; }
     206void nlOff( ifstream & os ) { os.nlOnOff = false; }
     207bool getANL( ifstream & os ) { return os.nlOnOff; }
    208208
    209209int fail( ifstream & is ) {
    210         return is.$file == 0p || ferror( (FILE *)(is.$file) );
     210        return is.file == 0 || ferror( (FILE *)(is.file) );
    211211} // fail
    212212
    213213int eof( ifstream & is ) {
    214         return feof( (FILE *)(is.$file) );
     214        return feof( (FILE *)(is.file) );
    215215} // eof
    216216
    217 void open( ifstream & is, const char name[], const char mode[] ) {
     217void open( ifstream & is, const char * name, const char * mode ) {
    218218        FILE * file = fopen( name, mode );
    219219        #ifdef __CFA_DEBUG__
    220         if ( file == 0p ) {
     220        if ( file == 0 ) {
    221221                abort | IO_MSG "open input file \"" | name | "\"" | nl | strerror( errno );
    222222        } // if
    223223        #endif // __CFA_DEBUG__
    224         is.$file = file;
    225 } // open
    226 
    227 void open( ifstream & is, const char name[] ) {
     224        is.file = file;
     225} // open
     226
     227void open( ifstream & is, const char * name ) {
    228228        open( is, name, "r" );
    229229} // open
    230230
    231231void close( ifstream & is ) {
    232         if ( (FILE *)(is.$file) == stdin ) return;
    233 
    234         if ( fclose( (FILE *)(is.$file) ) == EOF ) {
     232        if ( (FILE *)(is.file) == stdin ) return;
     233
     234        if ( fclose( (FILE *)(is.file) ) == EOF ) {
    235235                abort | IO_MSG "close input" | nl | strerror( errno );
    236236        } // if
     
    242242        } // if
    243243
    244         if ( fread( data, size, 1, (FILE *)(is.$file) ) == 0 ) {
     244        if ( fread( data, size, 1, (FILE *)(is.file) ) == 0 ) {
    245245                abort | IO_MSG "read" | nl | strerror( errno );
    246246        } // if
     
    253253        } // if
    254254
    255         if ( ungetc( c, (FILE *)(is.$file) ) == EOF ) {
     255        if ( ungetc( c, (FILE *)(is.file) ) == EOF ) {
    256256                abort | IO_MSG "ungetc" | nl | strerror( errno );
    257257        } // if
     
    263263
    264264        va_start( args, format );
    265         int len = vfscanf( (FILE *)(is.$file), format, args );
     265        int len = vfscanf( (FILE *)(is.file), format, args );
    266266        if ( len == EOF ) {
    267                 if ( ferror( (FILE *)(is.$file) ) ) {
     267                if ( ferror( (FILE *)(is.file) ) ) {
    268268                        abort | IO_MSG "invalid read";
    269269                } // if
  • libcfa/src/fstream.hfa

    ra505021 r8c50aed  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Feb 17 08:29:23 2020
    13 // Update Count     : 175
     12// Last Modified On : Fri Nov 29 06:56:02 2019
     13// Update Count     : 168
    1414//
    1515
     
    2424enum { sepSize = 16 };
    2525struct ofstream {
    26         void * $file;
    27         bool $sepDefault;
    28         bool $sepOnOff;
    29         bool $nlOnOff;
    30         bool $prt;                                                                                      // print text
    31         bool $sawNL;
    32         const char * $sepCur;
    33         char $separator[sepSize];
    34         char $tupleSeparator[sepSize];
     26        void * file;
     27        bool sepDefault;
     28        bool sepOnOff;
     29        bool nlOnOff;
     30        bool prt;                                                                                       // print text
     31        bool sawNL;
     32        const char * sepCur;
     33        char separator[sepSize];
     34        char tupleSeparator[sepSize];
    3535}; // ofstream
    3636
    3737// private
    38 bool $sepPrt( ofstream & );
    39 void $sepReset( ofstream & );
    40 void $sepReset( ofstream &, bool );
    41 const char * $sepGetCur( ofstream & );
    42 void $sepSetCur( ofstream &, const char [] );
    43 bool $getNL( ofstream & );
    44 void $setNL( ofstream &, bool );
    45 bool $getANL( ofstream & );
    46 bool $getPrt( ofstream & );
    47 void $setPrt( ofstream &, bool );
     38bool sepPrt( ofstream & );
     39void sepReset( ofstream & );
     40void sepReset( ofstream &, bool );
     41const char * sepGetCur( ofstream & );
     42void sepSetCur( ofstream &, const char * );
     43bool getNL( ofstream & );
     44void setNL( ofstream &, bool );
     45bool getANL( ofstream & );
     46bool getPrt( ofstream & );
     47void setPrt( ofstream &, bool );
    4848
    4949// public
     
    5656
    5757const char * sepGet( ofstream & );
    58 void sepSet( ofstream &, const char [] );
     58void sepSet( ofstream &, const char * );
    5959const char * sepGetTuple( ofstream & );
    60 void sepSetTuple( ofstream &, const char [] );
     60void sepSetTuple( ofstream &, const char * );
    6161
    6262void ends( ofstream & os );
    6363int fail( ofstream & );
    6464int flush( ofstream & );
    65 void open( ofstream &, const char name[], const char mode[] );
    66 void open( ofstream &, const char name[] );
     65void open( ofstream &, const char * name, const char * mode );
     66void open( ofstream &, const char * name );
    6767void close( ofstream & );
    68 ofstream & write( ofstream &, const char data[], size_t size );
    69 int fmt( ofstream &, const char format[], ... ) __attribute__(( format(printf, 2, 3) ));
     68ofstream & write( ofstream &, const char * data, size_t size );
     69int fmt( ofstream &, const char format[], ... );
    7070
    7171void ?{}( ofstream & os );
    72 void ?{}( ofstream & os, const char name[], const char mode[] );
    73 void ?{}( ofstream & os, const char name[] );
     72void ?{}( ofstream & os, const char * name, const char * mode );
     73void ?{}( ofstream & os, const char * name );
    7474void ^?{}( ofstream & os );
    7575
     
    8282
    8383struct ifstream {
    84         void * $file;
    85         bool $nlOnOff;
     84        void * file;
     85        bool nlOnOff;
    8686}; // ifstream
    8787
     
    9292int fail( ifstream & is );
    9393int eof( ifstream & is );
    94 void open( ifstream & is, const char name[], const char mode[] );
    95 void open( ifstream & is, const char name[] );
     94void open( ifstream & is, const char * name, const char * mode );
     95void open( ifstream & is, const char * name );
    9696void close( ifstream & is );
    9797ifstream & read( ifstream & is, char * data, size_t size );
    9898ifstream & ungetc( ifstream & is, char c );
    99 int fmt( ifstream &, const char format[], ... ) __attribute__(( format(scanf, 2, 3) ));
     99int fmt( ifstream &, const char format[], ... );
    100100
    101101void ?{}( ifstream & is );
    102 void ?{}( ifstream & is, const char name[], const char mode[] );
    103 void ?{}( ifstream & is, const char name[] );
     102void ?{}( ifstream & is, const char * name, const char * mode );
     103void ?{}( ifstream & is, const char * name );
    104104void ^?{}( ifstream & is );
    105105
  • libcfa/src/gmp.hfa

    ra505021 r8c50aed  
    1010// Created On       : Tue Apr 19 08:43:43 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Feb  9 09:56:54 2020
    13 // Update Count     : 31
     12// Last Modified On : Sat Jul 13 15:25:05 2019
     13// Update Count     : 27
    1414//
    1515
     
    2424
    2525static inline {
    26         // constructor, zero_t/one_t are unnecessary because of relationship with signed/unsigned int
     26        // constructor
    2727        void ?{}( Int & this ) { mpz_init( this.mpz ); }
    2828        void ?{}( Int & this, Int init ) { mpz_init_set( this.mpz, init.mpz ); }
     29        void ?{}( Int & this, zero_t ) { mpz_init_set_si( this.mpz, 0 ); }
     30        void ?{}( Int & this, one_t ) { mpz_init_set_si( this.mpz, 1 ); }
    2931        void ?{}( Int & this, signed long int init ) { mpz_init_set_si( this.mpz, init ); }
    3032        void ?{}( Int & this, unsigned long int init ) { mpz_init_set_ui( this.mpz, init ); }
    31         void ?{}( Int & this, const char val[] ) { if ( mpz_init_set_str( this.mpz, val, 0 ) ) abort(); }
     33        void ?{}( Int & this, const char * val ) { if ( mpz_init_set_str( this.mpz, val, 0 ) ) abort(); }
    3234        void ^?{}( Int & this ) { mpz_clear( this.mpz ); }
    3335
     
    3537        Int ?`mp( signed long int init ) { return (Int){ init }; }
    3638        Int ?`mp( unsigned long int init ) { return (Int){ init }; }
    37         Int ?`mp( const char init[] ) { return (Int){ init }; }
     39        Int ?`mp( const char * init ) { return (Int){ init }; }
    3840
    3941        // assignment
     
    4143        Int ?=?( Int & lhs, long int rhs ) { mpz_set_si( lhs.mpz, rhs ); return lhs; }
    4244        Int ?=?( Int & lhs, unsigned long int rhs ) { mpz_set_ui( lhs.mpz, rhs ); return lhs; }
    43         Int ?=?( Int & lhs, const char rhs[] ) { if ( mpz_set_str( lhs.mpz, rhs, 0 ) ) { abort | "invalid string conversion"; } return lhs; }
     45        Int ?=?( Int & lhs, const char * rhs ) { if ( mpz_set_str( lhs.mpz, rhs, 0 ) ) { abort | "invalid string conversion"; } return lhs; }
    4446
    4547        char ?=?( char & lhs, Int rhs ) { char val = mpz_get_si( rhs.mpz ); lhs = val; return lhs; }
     
    263265        forall( dtype ostype | ostream( ostype ) ) {
    264266                ostype & ?|?( ostype & os, Int mp ) {
    265                         if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     267                        if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    266268                        gmp_printf( "%Zd", mp.mpz );
    267269                        sepOn( os );
  • libcfa/src/heap.cfa

    ra505021 r8c50aed  
    1010// Created On       : Tue Dec 19 21:58:35 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Feb  4 10:04:51 2020
    13 // Update Count     : 648
     12// Last Modified On : Sun Dec  8 21:01:31 2019
     13// Update Count     : 647
    1414//
    1515
     
    380380
    381381
    382 static inline void checkHeader( bool check, const char name[], void * addr ) {
     382static inline void checkHeader( bool check, const char * name, void * addr ) {
    383383        if ( unlikely( check ) ) {                                                      // bad address ?
    384384                abort( "Attempt to %s storage %p with address outside the heap.\n"
     
    418418
    419419
    420 static inline bool headers( const char name[] __attribute__(( unused )), void * addr, HeapManager.Storage.Header *& header, HeapManager.FreeHeader *& freeElem, size_t & size, size_t & alignment ) with ( heapManager ) {
     420static inline bool headers( const char * name __attribute__(( unused )), void * addr, HeapManager.Storage.Header *& header, HeapManager.FreeHeader *& freeElem, size_t & size, size_t & alignment ) with ( heapManager ) {
    421421        header = headerAddr( addr );
    422422
  • libcfa/src/interpose.cfa

    ra505021 r8c50aed  
    1010// Created On       : Wed Mar 29 16:10:31 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Feb 17 10:18:53 2020
    13 // Update Count     : 166
     12// Last Modified On : Thu Jan 30 17:47:32 2020
     13// Update Count     : 156
    1414//
    1515
     
    2929#include "bits/signal.hfa"                                                              // sigHandler_?
    3030#include "startup.hfa"                                                                  // STARTUP_PRIORITY_CORE
    31 #include <assert.h>
    3231
    3332//=============================================================================================
     
    4140
    4241typedef void (* generic_fptr_t)(void);
    43 generic_fptr_t interpose_symbol( const char symbol[], const char version[] ) {
     42generic_fptr_t interpose_symbol( const char * symbol, const char * version ) {
    4443        const char * error;
    4544
     
    146145extern "C" {
    147146        void abort( void ) __attribute__(( __nothrow__, __leaf__, __noreturn__ )) {
    148                 abort( false, "%s", "" );
     147                abort( false, NULL ); // FIX ME: 0p does not work
    149148        }
    150149
     
    162161
    163162void * kernel_abort( void ) __attribute__(( __nothrow__, __leaf__, __weak__ )) { return 0p; }
    164 void kernel_abort_msg( void * data, char buffer[], int size ) __attribute__(( __nothrow__, __leaf__, __weak__ )) {}
     163void kernel_abort_msg( void * data, char * buffer, int size ) __attribute__(( __nothrow__, __leaf__, __weak__ )) {}
    165164// See concurrency/kernel.cfa for strong definition used in multi-processor mode.
    166165int kernel_abort_lastframe( void ) __attribute__(( __nothrow__, __leaf__, __weak__ )) { return 4; }
     
    170169
    171170static void __cfaabi_backtrace( int start ) {
    172         enum { Frames = 50, };                                                          // maximum number of stack frames
     171        enum {
     172                Frames = 50,                                                                    // maximum number of stack frames
     173        };
    173174        int last = kernel_abort_lastframe();                            // skip last N stack frames
    174175
    175176        void * array[Frames];
    176177        size_t size = backtrace( array, Frames );
    177         char ** messages = backtrace_symbols( array, size ); // does not demangle names
     178        char ** messages = backtrace_symbols( array, size );
    178179
    179180        *index( messages[0], '(' ) = '\0';                                      // find executable name
     
    183184                char * name = 0p, * offset_begin = 0p, * offset_end = 0p;
    184185
    185                 for ( char * p = messages[i]; *p; p += 1 ) {    // find parantheses and +offset
     186                for ( char * p = messages[i]; *p; ++p ) {               // find parantheses and +offset
    186187                        //__cfaabi_bits_print_nolock( "X %s\n", p);
    187188                        if ( *p == '(' ) {
     
    227228        __cfaabi_bits_write( STDERR_FILENO, abort_text, len );
    228229
    229         assert( fmt );
    230         va_list args;
    231         va_start( args, fmt );
    232 
    233         len = vsnprintf( abort_text, abort_text_size, fmt, args );
    234         va_end( args );
    235         __cfaabi_bits_write( STDERR_FILENO, abort_text, len );
    236 
    237         if ( fmt[strlen( fmt ) - 1] != '\n' ) {                         // add optional newline if missing at the end of the format text
    238                 __cfaabi_dbg_write( "\n", 1 );
    239         } // if
     230        if ( fmt ) {
     231                va_list args;
     232                va_start( args, fmt );
     233
     234                len = vsnprintf( abort_text, abort_text_size, fmt, args );
     235                va_end( args );
     236                __cfaabi_bits_write( STDERR_FILENO, abort_text, len );
     237
     238                if ( fmt[strlen( fmt ) - 1] != '\n' ) {                 // add optional newline if missing at the end of the format text
     239                        __cfaabi_dbg_write( "\n", 1 );
     240                }
     241        }
     242
    240243        kernel_abort_msg( kernel_data, abort_text, abort_text_size );
    241 
    242         __cfaabi_backtrace( signalAbort ? 4 : 2 );
     244        __cfaabi_backtrace( signalAbort ? 4 : 3 );
    243245
    244246        __cabi_libc.abort();                                                            // print stack trace in handler
  • libcfa/src/iostream.cfa

    ra505021 r8c50aed  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Feb 20 15:53:23 2020
    13 // Update Count     : 829
     12// Last Modified On : Sat Jul 13 08:07:59 2019
     13// Update Count     : 821
    1414//
    1515
     
    1919#include <stdio.h>
    2020#include <stdbool.h>                                                                    // true/false
    21 #include <stdint.h>                                                                             // UINT64_MAX
    2221//#include <string.h>                                                                   // strlen, strcmp
    2322extern size_t strlen (const char *__s) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1)));
     
    3635forall( dtype ostype | ostream( ostype ) ) {
    3736        ostype & ?|?( ostype & os, zero_t ) {
    38                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     37                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    3938                fmt( os, "%d", 0n );
    4039                return os;
     
    4544
    4645        ostype & ?|?( ostype & os, one_t ) {
    47                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     46                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    4847                fmt( os, "%d", 1n );
    4948                return os;
     
    5453
    5554        ostype & ?|?( ostype & os, bool b ) {
    56                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     55                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    5756                fmt( os, "%s", b ? "true" : "false" );
    5857                return os;
     
    6463        ostype & ?|?( ostype & os, char c ) {
    6564                fmt( os, "%c", c );
    66                 if ( c == '\n' ) $setNL( os, true );
     65                if ( c == '\n' ) setNL( os, true );
    6766                return sepOff( os );
    6867        } // ?|?
     
    7271
    7372        ostype & ?|?( ostype & os, signed char sc ) {
    74                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     73                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    7574                fmt( os, "%hhd", sc );
    7675                return os;
     
    8180
    8281        ostype & ?|?( ostype & os, unsigned char usc ) {
    83                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     82                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    8483                fmt( os, "%hhu", usc );
    8584                return os;
     
    9089
    9190        ostype & ?|?( ostype & os, short int si ) {
    92                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     91                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    9392                fmt( os, "%hd", si );
    9493                return os;
     
    9998
    10099        ostype & ?|?( ostype & os, unsigned short int usi ) {
    101                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     100                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    102101                fmt( os, "%hu", usi );
    103102                return os;
     
    108107
    109108        ostype & ?|?( ostype & os, int i ) {
    110                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     109                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    111110                fmt( os, "%d", i );
    112111                return os;
     
    117116
    118117        ostype & ?|?( ostype & os, unsigned int ui ) {
    119                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     118                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    120119                fmt( os, "%u", ui );
    121120                return os;
     
    126125
    127126        ostype & ?|?( ostype & os, long int li ) {
    128                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     127                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    129128                fmt( os, "%ld", li );
    130129                return os;
     
    135134
    136135        ostype & ?|?( ostype & os, unsigned long int uli ) {
    137                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     136                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    138137                fmt( os, "%lu", uli );
    139138                return os;
     
    144143
    145144        ostype & ?|?( ostype & os, long long int lli ) {
    146                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     145                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    147146                fmt( os, "%lld", lli );
    148147                return os;
     
    153152
    154153        ostype & ?|?( ostype & os, unsigned long long int ulli ) {
    155                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     154                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    156155                fmt( os, "%llu", ulli );
    157156                return os;
     
    160159                (ostype &)(os | ulli); ends( os );
    161160        } // ?|?
    162 
    163 #if defined( __SIZEOF_INT128__ )
    164         //      UINT64_MAX 18_446_744_073_709_551_615_ULL
    165         #define P10_UINT64 10_000_000_000_000_000_000_ULL       // 19 zeroes
    166 
    167         static void base10_128( ostype & os, unsigned int128 val ) {
    168                 if ( val > UINT64_MAX ) {
    169                         base10_128( os, val / P10_UINT64 );                     // recursive
    170                         fmt( os, "%.19lu", (uint64_t)(val % P10_UINT64) );
    171                 } else {
    172                         fmt( os, "%lu", (uint64_t)val );
    173                 } // if
    174         } // base10_128
    175 
    176         static void base10_128( ostype & os, int128 val ) {
    177                 if ( val < 0 ) {
    178                         fmt( os, "-" );                                                         // leading negative sign
    179                         val = -val;
    180                 } // if
    181                 base10_128( os, (unsigned int128)val );                 // print zero/positive value
    182         } // base10_128
    183 
    184         ostype & ?|?( ostype & os, int128 llli ) {
    185                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
    186                 base10_128( os, llli );
    187                 return os;
    188         } // ?|?
    189         void & ?|?( ostype & os, int128 llli ) {
    190                 (ostype &)(os | llli); ends( os );
    191         } // ?|?
    192 
    193         ostype & ?|?( ostype & os, unsigned int128 ullli ) {
    194                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
    195                 base10_128( os, ullli );
    196                 return os;
    197         } // ?|?
    198         void & ?|?( ostype & os, unsigned int128 ullli ) {
    199                 (ostype &)(os | ullli); ends( os );
    200         } // ?|?
    201 #endif // __SIZEOF_INT128__
    202161
    203162        #define PrintWithDP( os, format, val, ... ) \
     
    216175
    217176        ostype & ?|?( ostype & os, float f ) {
    218                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     177                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    219178                PrintWithDP( os, "%g", f );
    220179                return os;
     
    225184
    226185        ostype & ?|?( ostype & os, double d ) {
    227                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     186                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    228187                PrintWithDP( os, "%.*lg", d, DBL_DIG );
    229188                return os;
     
    234193
    235194        ostype & ?|?( ostype & os, long double ld ) {
    236                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     195                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    237196                PrintWithDP( os, "%.*Lg", ld, LDBL_DIG );
    238197                return os;
     
    243202
    244203        ostype & ?|?( ostype & os, float _Complex fc ) {
    245                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     204                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    246205//              os | crealf( fc ) | nonl;
    247206                PrintWithDP( os, "%g", crealf( fc ) );
     
    255214
    256215        ostype & ?|?( ostype & os, double _Complex dc ) {
    257                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     216                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    258217//              os | creal( dc ) | nonl;
    259218                PrintWithDP( os, "%.*lg", creal( dc ), DBL_DIG );
     
    267226
    268227        ostype & ?|?( ostype & os, long double _Complex ldc ) {
    269                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     228                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    270229//              os | creall( ldc ) || nonl;
    271230                PrintWithDP( os, "%.*Lg", creall( ldc ), LDBL_DIG );
     
    278237        } // ?|?
    279238
    280         ostype & ?|?( ostype & os, const char str[] ) {
     239        ostype & ?|?( ostype & os, const char * str ) {
    281240                enum { Open = 1, Close, OpenClose };
    282241                static const unsigned char mask[256] @= {
     
    298257                // first character IS NOT spacing or closing punctuation => add left separator
    299258                unsigned char ch = str[0];                                              // must make unsigned
    300                 if ( $sepPrt( os ) && mask[ ch ] != Close && mask[ ch ] != OpenClose ) {
    301                         fmt( os, "%s", $sepGetCur( os ) );
     259                if ( sepPrt( os ) && mask[ ch ] != Close && mask[ ch ] != OpenClose ) {
     260                        fmt( os, "%s", sepGetCur( os ) );
    302261                } // if
    303262
    304263                // if string starts line, must reset to determine open state because separator is off
    305                 $sepReset( os );                                                                // reset separator
     264                sepReset( os );                                                                 // reset separator
    306265
    307266                // last character IS spacing or opening punctuation => turn off separator for next item
    308267                size_t len = strlen( str );
    309268                ch = str[len - 1];                                                              // must make unsigned
    310                 if ( $sepPrt( os ) && mask[ ch ] != Open && mask[ ch ] != OpenClose ) {
     269                if ( sepPrt( os ) && mask[ ch ] != Open && mask[ ch ] != OpenClose ) {
    311270                        sepOn( os );
    312271                } else {
    313272                        sepOff( os );
    314273                } // if
    315                 if ( ch == '\n' ) $setNL( os, true );                   // check *AFTER* $sepPrt call above as it resets NL flag
     274                if ( ch == '\n' ) setNL( os, true );                    // check *AFTER* sepPrt call above as it resets NL flag
    316275                return write( os, str, len );
    317276        } // ?|?
    318 
    319         void ?|?( ostype & os, const char str[] ) {
     277        void ?|?( ostype & os, const char * str ) {
    320278                (ostype &)(os | str); ends( os );
    321279        } // ?|?
    322280
    323281//      ostype & ?|?( ostype & os, const char16_t * str ) {
    324 //              if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     282//              if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    325283//              fmt( os, "%ls", str );
    326284//              return os;
     
    329287// #if ! ( __ARM_ARCH_ISA_ARM == 1 && __ARM_32BIT_STATE == 1 ) // char32_t == wchar_t => ambiguous
    330288//      ostype & ?|?( ostype & os, const char32_t * str ) {
    331 //              if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     289//              if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    332290//              fmt( os, "%ls", str );
    333291//              return os;
     
    336294
    337295//      ostype & ?|?( ostype & os, const wchar_t * str ) {
    338 //              if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     296//              if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    339297//              fmt( os, "%ls", str );
    340298//              return os;
     
    342300
    343301        ostype & ?|?( ostype & os, const void * p ) {
    344                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     302                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    345303                fmt( os, "%p", p );
    346304                return os;
     
    357315        void ?|?( ostype & os, ostype & (* manip)( ostype & ) ) {
    358316                (ostype &)(manip( os ));
    359                 if ( $getPrt( os ) ) ends( os );                                // something printed ?
    360                 $setPrt( os, false );                                                   // turn off
     317                if ( getPrt( os ) ) ends( os );                                 // something printed ?
     318                setPrt( os, false );                                                    // turn off
    361319        } // ?|?
    362320
     
    371329        ostype & nl( ostype & os ) {
    372330                (ostype &)(os | '\n');
    373                 $setPrt( os, false );                                                   // turn off
    374                 $setNL( os, true );
     331                setPrt( os, false );                                                    // turn off
     332                setNL( os, true );
    375333                flush( os );
    376334                return sepOff( os );                                                    // prepare for next line
     
    378336
    379337        ostype & nonl( ostype & os ) {
    380                 $setPrt( os, false );                                                   // turn off
     338                setPrt( os, false );                                                    // turn off
    381339                return os;
    382340        } // nonl
     
    417375        ostype & ?|?( ostype & os, T arg, Params rest ) {
    418376                (ostype &)(os | arg);                                                   // print first argument
    419                 $sepSetCur( os, sepGetTuple( os ) );                    // switch to tuple separator
     377                sepSetCur( os, sepGetTuple( os ) );                             // switch to tuple separator
    420378                (ostype &)(os | rest);                                                  // print remaining arguments
    421                 $sepSetCur( os, sepGet( os ) );                                 // switch to regular separator
     379                sepSetCur( os, sepGet( os ) );                                  // switch to regular separator
    422380                return os;
    423381        } // ?|?
     
    425383                // (ostype &)(?|?( os, arg, rest )); ends( os );
    426384                (ostype &)(os | arg);                                                   // print first argument
    427                 $sepSetCur( os, sepGetTuple( os ) );                    // switch to tuple separator
     385                sepSetCur( os, sepGetTuple( os ) );                             // switch to tuple separator
    428386                (ostype &)(os | rest);                                                  // print remaining arguments
    429                 $sepSetCur( os, sepGet( os ) );                                 // switch to regular separator
     387                sepSetCur( os, sepGet( os ) );                                  // switch to regular separator
    430388                ends( os );
    431389        } // ?|?
     
    456414forall( dtype ostype | ostream( ostype ) ) { \
    457415        ostype & ?|?( ostype & os, _Ostream_Manip(T) f ) { \
    458                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) ); \
     416                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) ); \
    459417\
    460418                if ( f.base == 'b' || f.base == 'B' ) {                 /* bespoke binary format */ \
     
    505463\
    506464                if ( ! f.flags.pc ) {                                                   /* no precision */ \
     465                        /* printf( "%s\n", &fmtstr[star] ); */ \
    507466                        fmtstr[sizeof(IFMTNP)-2] = f.base;                      /* sizeof includes '\0' */ \
    508                         /* printf( "%s %c %c\n", &fmtstr[star], f.base, CODE ); */ \
    509467                        fmt( os, &fmtstr[star], f.wd, f.val ); \
    510468                } else {                                                                                /* precision */ \
    511469                        fmtstr[sizeof(IFMTP)-2] = f.base;                       /* sizeof includes '\0' */ \
    512                         /* printf( "%s %c %c\n", &fmtstr[star], f.base, CODE ); */ \
     470                        /* printf( "%s\n", &fmtstr[star] ); */ \
    513471                        fmt( os, &fmtstr[star], f.wd, f.pc, f.val ); \
    514472                } /* if */ \
     
    528486IntegralFMTImpl( signed long long int, 'd', "%    *ll ", "%    *.*ll " )
    529487IntegralFMTImpl( unsigned long long int, 'u', "%    *ll ", "%    *.*ll " )
    530 
    531 
    532 #if defined( __SIZEOF_INT128__ )
    533 // Default prefix for non-decimal prints is 0b, 0, 0x.
    534 #define IntegralFMTImpl128( T, SIGNED, CODE, IFMTNP, IFMTP ) \
    535 forall( dtype ostype | ostream( ostype ) ) \
    536 static void base10_128( ostype & os, _Ostream_Manip(T) fmt ) { \
    537         if ( fmt.val > UINT64_MAX ) { \
    538                 fmt.val /= P10_UINT64; \
    539                 base10_128( os, fmt ); /* recursive */ \
    540                 _Ostream_Manip(unsigned long long int) fmt2 @= { (uint64_t)(fmt.val % P10_UINT64), 0, 19, 'u', { .all : 0 } }; \
    541                 fmt2.flags.nobsdp = true; \
    542                 printf( "fmt2 %c %lld %d\n", fmt2.base, fmt2.val, fmt2.all );   \
    543                 sepOff( os ); \
    544                 (ostype &)(os | fmt2); \
    545         } else { \
    546                 printf( "fmt %c %lld %d\n", fmt.base, fmt.val, fmt.all ); \
    547                 (ostype &)(os | fmt); \
    548         } /* if */ \
    549 } /* base10_128 */                                                 \
    550 forall( dtype ostype | ostream( ostype ) ) { \
    551         ostype & ?|?( ostype & os, _Ostream_Manip(T) f ) { \
    552                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) ); \
    553 \
    554                 if ( f.base == 'b' | f.base == 'o' | f.base == 'x' | f.base == 'X' ) { \
    555                         unsigned long long int msig = (unsigned long long int)(f.val >> 64); \
    556                         unsigned long long int lsig = (unsigned long long int)(f.val); \
    557                         _Ostream_Manip(SIGNED long long int) fmt @= { msig, f.wd, f.pc, f.base, { .all : f.all } }; \
    558                         _Ostream_Manip(unsigned long long int) fmt2 @= { lsig, 0, 0, f.base, { .all : 0 } }; \
    559                         if ( msig == 0 ) { \
    560                                 fmt.val = lsig; \
    561                                 (ostype &)(os | fmt); \
    562                         } else { \
    563                                 fmt2.flags.pad0 = fmt2.flags.nobsdp = true;     \
    564                                 if ( f.base == 'b' ) { \
    565                                         if ( f.wd > 64 ) fmt.wd = f.wd - 64; \
    566                                         fmt2.wd = 64; \
    567                                         (ostype &)(os | fmt | "" | fmt2); \
    568                                 } else if ( f.base == 'o' ) { \
    569                                         fmt.val = (unsigned long long int)fmt.val >> 2; \
    570                                         if ( f.wd > 21 ) fmt.wd = f.wd - 21; \
    571                                         fmt2.wd = 1; \
    572                                         fmt2.val = ((msig & 0x3) << 1) + 1; \
    573                                         (ostype &)(os | fmt | "" | fmt2); \
    574                                         sepOff( os ); \
    575                                         fmt2.wd = 21; \
    576                                         fmt2.val = lsig & 0x7fffffffffffffff; \
    577                                         (ostype &)(os | fmt2); \
    578                                 } else { \
    579                                         if ( f.flags.left ) { \
    580                                                 if ( f.wd > 16 ) fmt2.wd = f.wd - 16;   \
    581                                                 fmt.wd = 16;                                                    \
    582                                         } else { \
    583                                                 if ( f.wd > 16 ) fmt.wd = f.wd - 16;    \
    584                                                 fmt2.wd = 16;                                                   \
    585                                         } /* if */ \
    586                                         (ostype &)(os | fmt | "" | fmt2); \
    587                                 } /* if */ \
    588                         } /* if */ \
    589                 } else { \
    590                         base10_128( os, f ); \
    591                 } /* if */ \
    592                 return os; \
    593         } /* ?|? */ \
    594         void ?|?( ostype & os, _Ostream_Manip(T) f ) { (ostype &)(os | f); ends( os ); } \
    595 } // distribution
    596 
    597 IntegralFMTImpl128( int128, signed, 'd', "%    *ll ", "%    *.*ll " )
    598 IntegralFMTImpl128( unsigned int128, unsigned, 'u', "%    *ll ", "%    *.*ll " )
    599 #endif // __SIZEOF_INT128__
    600488
    601489//*********************************** floating point ***********************************
     
    625513forall( dtype ostype | ostream( ostype ) ) { \
    626514        ostype & ?|?( ostype & os, _Ostream_Manip(T) f ) { \
    627                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) ); \
     515                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) ); \
    628516                char fmtstr[sizeof(DFMTP)];                                             /* sizeof includes '\0' */ \
    629517                if ( ! f.flags.pc ) memcpy( &fmtstr, DFMTNP, sizeof(DFMTNP) ); \
     
    648536                return os; \
    649537        } /* ?|? */ \
    650 \
    651538        void ?|?( ostype & os, _Ostream_Manip(T) f ) { (ostype &)(os | f); ends( os ); } \
    652539} // distribution
     
    668555                } // if
    669556
    670                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     557                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    671558
    672559                #define CFMTNP "% * "
     
    684571                return os;
    685572        } // ?|?
    686 
    687573        void ?|?( ostype & os, _Ostream_Manip(char) f ) { (ostype &)(os | f); ends( os ); }
    688574} // distribution
     
    706592                } // if
    707593
    708                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     594                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    709595
    710596                #define SFMTNP "% * "
     
    730616                return os;
    731617        } // ?|?
    732 
    733618        void ?|?( ostype & os, _Ostream_Manip(const char *) f ) { (ostype &)(os | f); ends( os ); }
    734619} // distribution
     
    850735        } // ?|?
    851736
    852         // istype & ?|?( istype & is, const char fmt[] ) {
     737        // istype & ?|?( istype & is, const char * fmt ) {
    853738        //      fmt( is, fmt, "" );
    854739        //      return is;
  • libcfa/src/iostream.hfa

    ra505021 r8c50aed  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Feb 20 15:30:56 2020
    13 // Update Count     : 337
     12// Last Modified On : Fri Jul 12 12:08:38 2019
     13// Update Count     : 334
    1414//
    1515
     
    2424trait ostream( dtype ostype ) {
    2525        // private
    26         bool $sepPrt( ostype & );                                                       // get separator state (on/off)
    27         void $sepReset( ostype & );                                                     // set separator state to default state
    28         void $sepReset( ostype &, bool );                                       // set separator and default state
    29         const char * $sepGetCur( ostype & );                            // get current separator string
    30         void $sepSetCur( ostype &, const char [] );                     // set current separator string
    31         bool $getNL( ostype & );                                                        // check newline
    32         void $setNL( ostype &, bool );                                          // saw newline
    33         bool $getANL( ostype & );                                                       // get auto newline (on/off)
    34         bool $getPrt( ostype & );                                                       // get fmt called in output cascade
    35         void $setPrt( ostype &, bool );                                         // set fmt called in output cascade
     26        bool sepPrt( ostype & );                                                        // get separator state (on/off)
     27        void sepReset( ostype & );                                                      // set separator state to default state
     28        void sepReset( ostype &, bool );                                        // set separator and default state
     29        const char * sepGetCur( ostype & );                                     // get current separator string
     30        void sepSetCur( ostype &, const char * );                       // set current separator string
     31        bool getNL( ostype & );                                                         // check newline
     32        void setNL( ostype &, bool );                                           // saw newline
     33        bool getANL( ostype & );                                                        // get auto newline (on/off)
     34        bool getPrt( ostype & );                                                        // get fmt called in output cascade
     35        void setPrt( ostype &, bool );                                          // set fmt called in output cascade
    3636        // public
    3737        void sepOn( ostype & );                                                         // turn separator state on
     
    4343
    4444        const char * sepGet( ostype & );                                        // get separator string
    45         void sepSet( ostype &, const char [] );                         // set separator to string (15 character maximum)
     45        void sepSet( ostype &, const char * );                          // set separator to string (15 character maximum)
    4646        const char * sepGetTuple( ostype & );                           // get tuple separator string
    47         void sepSetTuple( ostype &, const char [] );            // set tuple separator to string (15 character maximum)
     47        void sepSetTuple( ostype &, const char * );                     // set tuple separator to string (15 character maximum)
    4848
    4949        void ends( ostype & os );                                                       // end of output statement
    5050        int fail( ostype & );
    5151        int flush( ostype & );
    52         void open( ostype & os, const char name[], const char mode[] );
     52        void open( ostype & os, const char * name, const char * mode );
    5353        void close( ostype & os );
    54         ostype & write( ostype &, const char [], size_t );
     54        ostype & write( ostype &, const char *, size_t );
    5555        int fmt( ostype &, const char format[], ... ) __attribute__(( format(printf, 2, 3) ));
    5656}; // ostream
     
    9898        ostype & ?|?( ostype &, unsigned long long int );
    9999        void ?|?( ostype &, unsigned long long int );
    100 #if defined( __SIZEOF_INT128__ )
    101         ostype & ?|?( ostype &, int128 );
    102         void ?|?( ostype &, int128 );
    103         ostype & ?|?( ostype &, unsigned int128 );
    104         void ?|?( ostype &, unsigned int128 );
    105 #endif // __SIZEOF_INT128__
    106100
    107101        ostype & ?|?( ostype &, float );
     
    119113        void ?|?( ostype &, long double _Complex );
    120114
    121         ostype & ?|?( ostype &, const char [] );
    122         void ?|?( ostype &, const char [] );
     115        ostype & ?|?( ostype &, const char * );
     116        void ?|?( ostype &, const char * );
    123117        // ostype & ?|?( ostype &, const char16_t * );
    124118#if ! ( __ARM_ARCH_ISA_ARM == 1 && __ARM_32BIT_STATE == 1 ) // char32_t == wchar_t => ambiguous
     
    212206IntegralFMTDecl( signed long long int, 'd' )
    213207IntegralFMTDecl( unsigned long long int, 'u' )
    214 #if defined( __SIZEOF_INT128__ )
    215 IntegralFMTDecl( int128, 'd' )
    216 IntegralFMTDecl( unsigned int128, 'u' )
    217 #endif
    218208
    219209//*********************************** floating point ***********************************
     
    266256
    267257static inline {
    268         _Ostream_Manip(const char *) bin( const char s[] ) { return (_Ostream_Manip(const char *))@{ s, 1, 0, 'b', { .all : 0 } }; }
    269         _Ostream_Manip(const char *) oct( const char s[] ) { return (_Ostream_Manip(const char *))@{ s, 1, 0, 'o', { .all : 0 } }; }
    270         _Ostream_Manip(const char *) hex( const char s[] ) { return (_Ostream_Manip(const char *))@{ s, 1, 0, 'x', { .all : 0 } }; }
    271         _Ostream_Manip(const char *) wd( unsigned int w, const char s[] ) { return (_Ostream_Manip(const char *))@{ s, w, 0, 's', { .all : 0 } }; }
    272         _Ostream_Manip(const char *) wd( unsigned int w, unsigned char pc, const char s[] ) { return (_Ostream_Manip(const char *))@{ s, w, pc, 's', { .flags.pc : true } }; }
     258        _Ostream_Manip(const char *) bin( const char * s ) { return (_Ostream_Manip(const char *))@{ s, 1, 0, 'b', { .all : 0 } }; }
     259        _Ostream_Manip(const char *) oct( const char * s ) { return (_Ostream_Manip(const char *))@{ s, 1, 0, 'o', { .all : 0 } }; }
     260        _Ostream_Manip(const char *) hex( const char * s ) { return (_Ostream_Manip(const char *))@{ s, 1, 0, 'x', { .all : 0 } }; }
     261        _Ostream_Manip(const char *) wd( unsigned int w, const char * s ) { return (_Ostream_Manip(const char *))@{ s, w, 0, 's', { .all : 0 } }; }
     262        _Ostream_Manip(const char *) wd( unsigned int w, unsigned char pc, const char * s ) { return (_Ostream_Manip(const char *))@{ s, w, pc, 's', { .flags.pc : true } }; }
    273263        _Ostream_Manip(const char *) & wd( unsigned int w, _Ostream_Manip(const char *) & fmt ) { fmt.wd = w; return fmt; }
    274264        _Ostream_Manip(const char *) & wd( unsigned int w, unsigned char pc, _Ostream_Manip(const char *) & fmt ) { fmt.wd = w; fmt.pc = pc; fmt.flags.pc = true; return fmt; }
     
    291281        int fail( istype & );
    292282        int eof( istype & );
    293         void open( istype & is, const char name[] );
     283        void open( istype & is, const char * name );
    294284        void close( istype & is );
    295285        istype & read( istype &, char *, size_t );
     
    326316        istype & ?|?( istype &, long double _Complex & );
    327317
    328 //      istype & ?|?( istype &, const char [] );
     318//      istype & ?|?( istype &, const char * );
    329319        istype & ?|?( istype &, char * );
    330320
     
    353343static inline {
    354344        _Istream_Cstr skip( unsigned int n ) { return (_Istream_Cstr){ 0p, 0p, n, { .all : 0 } }; }
    355         _Istream_Cstr skip( const char scanset[] ) { return (_Istream_Cstr){ 0p, scanset, -1, { .all : 0 } }; }
    356         _Istream_Cstr incl( const char scanset[], char * s ) { return (_Istream_Cstr){ s, scanset, -1, { .flags.inex : false } }; }
    357         _Istream_Cstr & incl( const char scanset[], _Istream_Cstr & fmt ) { fmt.scanset = scanset; fmt.flags.inex = false; return fmt; }
    358         _Istream_Cstr excl( const char scanset[], char * s ) { return (_Istream_Cstr){ s, scanset, -1, { .flags.inex : true } }; }
    359         _Istream_Cstr & excl( const char scanset[], _Istream_Cstr & fmt ) { fmt.scanset = scanset; fmt.flags.inex = true; return fmt; }
    360         _Istream_Cstr ignore( const char s[] ) { return (_Istream_Cstr)@{ s, 0p, -1, { .flags.ignore : true } }; }
     345        _Istream_Cstr skip( const char * scanset ) { return (_Istream_Cstr){ 0p, scanset, -1, { .all : 0 } }; }
     346        _Istream_Cstr incl( const char * scanset, char * s ) { return (_Istream_Cstr){ s, scanset, -1, { .flags.inex : false } }; }
     347        _Istream_Cstr & incl( const char * scanset, _Istream_Cstr & fmt ) { fmt.scanset = scanset; fmt.flags.inex = false; return fmt; }
     348        _Istream_Cstr excl( const char * scanset, char * s ) { return (_Istream_Cstr){ s, scanset, -1, { .flags.inex : true } }; }
     349        _Istream_Cstr & excl( const char * scanset, _Istream_Cstr & fmt ) { fmt.scanset = scanset; fmt.flags.inex = true; return fmt; }
     350        _Istream_Cstr ignore( const char * s ) { return (_Istream_Cstr)@{ s, 0p, -1, { .flags.ignore : true } }; }
    361351        _Istream_Cstr & ignore( _Istream_Cstr & fmt ) { fmt.flags.ignore = true; return fmt; }
    362         _Istream_Cstr wdi( unsigned int w, char s[] ) { return (_Istream_Cstr)@{ s, 0p, w, { .all : 0 } }; }
     352        _Istream_Cstr wdi( unsigned int w, char * s ) { return (_Istream_Cstr)@{ s, 0p, w, { .all : 0 } }; }
    363353        _Istream_Cstr & wdi( unsigned int w, _Istream_Cstr & fmt ) { fmt.wd = w; return fmt; }
    364354} // distribution
  • libcfa/src/math.hfa

    ra505021 r8c50aed  
    1010// Created On       : Mon Apr 18 23:37:04 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Feb  4 10:27:11 2020
    13 // Update Count     : 117
     12// Last Modified On : Fri Jul 13 11:02:15 2018
     13// Update Count     : 116
    1414//
    1515
     
    5151static inline long double fdim( long double x, long double y ) { return fdiml( x, y ); }
    5252
    53 static inline float nan( const char tag[] ) { return nanf( tag ); }
    54 // extern "C" { double nan( const char [] ); }
    55 static inline long double nan( const char tag[] ) { return nanl( tag ); }
     53static inline float nan( const char * tag ) { return nanf( tag ); }
     54// extern "C" { double nan( const char * ); }
     55static inline long double nan( const char * tag ) { return nanl( tag ); }
    5656
    5757//---------------------- Exponential ----------------------
  • libcfa/src/rational.cfa

    ra505021 r8c50aed  
    1010// Created On       : Wed Apr  6 17:54:28 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Feb  8 17:56:36 2020
    13 // Update Count     : 187
     12// Last Modified On : Fri Jul 12 18:12:08 2019
     13// Update Count     : 184
    1414//
    1515
     
    5656        } // rational
    5757
    58         void ?{}( Rational(RationalImpl) & r, zero_t ) {
    59                 r{ (RationalImpl){0}, (RationalImpl){1} };
    60         } // rational
    61 
    62         void ?{}( Rational(RationalImpl) & r, one_t ) {
    63                 r{ (RationalImpl){1}, (RationalImpl){1} };
    64         } // rational
    6558
    6659        // getter for numerator/denominator
  • libcfa/src/startup.cfa

    ra505021 r8c50aed  
    1010// Created On       : Tue Jul 24 16:21:57 2018
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Feb  4 13:03:18 2020
    13 // Update Count     : 30
     12// Last Modified On : Fri Dec 13 13:16:45 2019
     13// Update Count     : 29
    1414//
    1515
     
    4141struct __spinlock_t;
    4242extern "C" {
    43         void __cfaabi_dbg_record(struct __spinlock_t & this, const char prev_name[]) __attribute__(( weak )) {}
     43        void __cfaabi_dbg_record(struct __spinlock_t & this, const char * prev_name) __attribute__(( weak )) {}
    4444}
    4545
  • libcfa/src/stdhdr/assert.h

    ra505021 r8c50aed  
    1010// Created On       : Mon Jul  4 23:25:26 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Feb  4 12:58:49 2020
    13 // Update Count     : 15
     12// Last Modified On : Mon Jul 31 23:09:32 2017
     13// Update Count     : 13
    1414//
    1515
     
    2727        #define assertf( expr, fmt, ... ) ((expr) ? ((void)0) : __assert_fail_f(__VSTRINGIFY__(expr), __FILE__, __LINE__, __PRETTY_FUNCTION__, fmt, ## __VA_ARGS__ ))
    2828
    29         void __assert_fail_f( const char assertion[], const char file[], unsigned int line, const char function[], const char fmt[], ... ) __attribute__((noreturn, format( printf, 5, 6) ));
     29        void __assert_fail_f( const char *assertion, const char *file, unsigned int line, const char *function, const char *fmt, ... ) __attribute__((noreturn, format( printf, 5, 6) ));
    3030#endif
    3131
  • libcfa/src/stdhdr/bfdlink.h

    ra505021 r8c50aed  
    1010// Created On       : Tue Jul 18 07:26:04 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Feb  7 19:05:08 2020
    13 // Update Count     : 6
     12// Last Modified On : Sat Feb  1 07:15:29 2020
     13// Update Count     : 5
    1414//
    1515
    1616// include file uses the CFA keyword "with".
    1717#if ! defined( with )                                                                   // nesting ?
    18 #define with ``with                                                                             // make keyword an identifier
     18#define with ``with``                                                                   // make keyword an identifier
    1919#define __CFA_BFDLINK_H__
    2020#endif
  • libcfa/src/stdhdr/hwloc.h

    ra505021 r8c50aed  
    1010// Created On       : Tue Jul 18 07:45:00 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Feb  7 19:05:18 2020
    13 // Update Count     : 6
     12// Last Modified On : Sat Feb  1 07:15:39 2020
     13// Update Count     : 5
    1414//
    1515
    1616// include file uses the CFA keyword "thread".
    1717#if ! defined( thread )                                                                 // nesting ?
    18 #define thread ``thread                                                                 // make keyword an identifier
     18#define thread ``thread``                                                               // make keyword an identifier
    1919#define __CFA_HWLOC_H__
    2020#endif
  • libcfa/src/stdhdr/krb5.h

    ra505021 r8c50aed  
    1010// Created On       : Tue Jul 18 07:55:44 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Feb  7 19:05:35 2020
    13 // Update Count     : 6
     12// Last Modified On : Sat Feb  1 07:15:47 2020
     13// Update Count     : 5
    1414//
    1515
    1616// include file uses the CFA keyword "enable".
    1717#if ! defined( enable )                                                                 // nesting ?
    18 #define enable ``enable                                                                 // make keyword an identifier
     18#define enable ``enable``                                                               // make keyword an identifier
    1919#define __CFA_KRB5_H__
    2020#endif
  • libcfa/src/stdhdr/math.h

    ra505021 r8c50aed  
    1010// Created On       : Mon Jul  4 23:25:26 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Feb  7 19:05:27 2020
    13 // Update Count     : 15
     12// Last Modified On : Sat Feb  1 07:15:58 2020
     13// Update Count     : 14
    1414//
    1515
    1616extern "C" {
    1717#if ! defined( exception )                                                              // nesting ?
    18 #define exception ``exception                                                   // make keyword an identifier
     18#define exception ``exception``                                                 // make keyword an identifier
    1919#define __CFA_MATH_H__
    2020#endif
  • libcfa/src/stdhdr/sys/ucontext.h

    ra505021 r8c50aed  
    1010// Created On       : Thu Feb  8 23:48:16 2018
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Feb  7 19:05:41 2020
    13 // Update Count     : 6
     12// Last Modified On : Sat Feb  1 07:16:05 2020
     13// Update Count     : 5
    1414//
    1515
    1616#if ! defined( ftype )                                                                  // nesting ?
    17 #define ftype ``ftype                                                                   // make keyword an identifier
     17#define ftype ``ftype``                                                                 // make keyword an identifier
    1818#define __CFA_UCONTEXT_H__
    1919#endif
  • libcfa/src/stdlib.cfa

    ra505021 r8c50aed  
    1010// Created On       : Thu Jan 28 17:10:29 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Feb  4 08:27:08 2020
    13 // Update Count     : 486
     12// Last Modified On : Wed Nov 20 17:22:47 2019
     13// Update Count     : 485
    1414//
    1515
     
    107107//---------------------------------------
    108108
    109 float _Complex strto( const char sptr[], char ** eptr ) {
     109float _Complex strto( const char * sptr, char ** eptr ) {
    110110        float re, im;
    111111        char * eeptr;
     
    118118} // strto
    119119
    120 double _Complex strto( const char sptr[], char ** eptr ) {
     120double _Complex strto( const char * sptr, char ** eptr ) {
    121121        double re, im;
    122122        char * eeptr;
     
    129129} // strto
    130130
    131 long double _Complex strto( const char sptr[], char ** eptr ) {
     131long double _Complex strto( const char * sptr, char ** eptr ) {
    132132        long double re, im;
    133133        char * eeptr;
  • libcfa/src/stdlib.hfa

    ra505021 r8c50aed  
    1010// Created On       : Thu Jan 28 17:12:35 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Feb  4 08:27:01 2020
    13 // Update Count     : 401
     12// Last Modified On : Fri Nov 29 23:08:02 2019
     13// Update Count     : 400
    1414//
    1515
     
    193193
    194194static inline {
    195         int strto( const char sptr[], char ** eptr, int base ) { return (int)strtol( sptr, eptr, base ); }
    196         unsigned int strto( const char sptr[], char ** eptr, int base ) { return (unsigned int)strtoul( sptr, eptr, base ); }
    197         long int strto( const char sptr[], char ** eptr, int base ) { return strtol( sptr, eptr, base ); }
    198         unsigned long int strto( const char sptr[], char ** eptr, int base ) { return strtoul( sptr, eptr, base ); }
    199         long long int strto( const char sptr[], char ** eptr, int base ) { return strtoll( sptr, eptr, base ); }
    200         unsigned long long int strto( const char sptr[], char ** eptr, int base ) { return strtoull( sptr, eptr, base ); }
    201 
    202         float strto( const char sptr[], char ** eptr ) { return strtof( sptr, eptr ); }
    203         double strto( const char sptr[], char ** eptr ) { return strtod( sptr, eptr ); }
    204         long double strto( const char sptr[], char ** eptr ) { return strtold( sptr, eptr ); }
    205 } // distribution
    206 
    207 float _Complex strto( const char sptr[], char ** eptr );
    208 double _Complex strto( const char sptr[], char ** eptr );
    209 long double _Complex strto( const char sptr[], char ** eptr );
     195        int strto( const char * sptr, char ** eptr, int base ) { return (int)strtol( sptr, eptr, base ); }
     196        unsigned int strto( const char * sptr, char ** eptr, int base ) { return (unsigned int)strtoul( sptr, eptr, base ); }
     197        long int strto( const char * sptr, char ** eptr, int base ) { return strtol( sptr, eptr, base ); }
     198        unsigned long int strto( const char * sptr, char ** eptr, int base ) { return strtoul( sptr, eptr, base ); }
     199        long long int strto( const char * sptr, char ** eptr, int base ) { return strtoll( sptr, eptr, base ); }
     200        unsigned long long int strto( const char * sptr, char ** eptr, int base ) { return strtoull( sptr, eptr, base ); }
     201
     202        float strto( const char * sptr, char ** eptr ) { return strtof( sptr, eptr ); }
     203        double strto( const char * sptr, char ** eptr ) { return strtod( sptr, eptr ); }
     204        long double strto( const char * sptr, char ** eptr ) { return strtold( sptr, eptr ); }
     205} // distribution
     206
     207float _Complex strto( const char * sptr, char ** eptr );
     208double _Complex strto( const char * sptr, char ** eptr );
     209long double _Complex strto( const char * sptr, char ** eptr );
    210210
    211211static inline {
    212         int ato( const char sptr[] ) { return (int)strtol( sptr, 0p, 10 ); }
    213         unsigned int ato( const char sptr[] ) { return (unsigned int)strtoul( sptr, 0p, 10 ); }
    214         long int ato( const char sptr[] ) { return strtol( sptr, 0p, 10 ); }
    215         unsigned long int ato( const char sptr[] ) { return strtoul( sptr, 0p, 10 ); }
    216         long long int ato( const char sptr[] ) { return strtoll( sptr, 0p, 10 ); }
    217         unsigned long long int ato( const char sptr[] ) { return strtoull( sptr, 0p, 10 ); }
    218 
    219         float ato( const char sptr[] ) { return strtof( sptr, 0p ); }
    220         double ato( const char sptr[] ) { return strtod( sptr, 0p ); }
    221         long double ato( const char sptr[] ) { return strtold( sptr, 0p ); }
    222 
    223         float _Complex ato( const char sptr[] ) { return strto( sptr, 0p ); }
    224         double _Complex ato( const char sptr[] ) { return strto( sptr, 0p ); }
    225         long double _Complex ato( const char sptr[] ) { return strto( sptr, 0p ); }
     212        int ato( const char * sptr ) { return (int)strtol( sptr, 0p, 10 ); }
     213        unsigned int ato( const char * sptr ) { return (unsigned int)strtoul( sptr, 0p, 10 ); }
     214        long int ato( const char * sptr ) { return strtol( sptr, 0p, 10 ); }
     215        unsigned long int ato( const char * sptr ) { return strtoul( sptr, 0p, 10 ); }
     216        long long int ato( const char * sptr ) { return strtoll( sptr, 0p, 10 ); }
     217        unsigned long long int ato( const char * sptr ) { return strtoull( sptr, 0p, 10 ); }
     218
     219        float ato( const char * sptr ) { return strtof( sptr, 0p ); }
     220        double ato( const char * sptr ) { return strtod( sptr, 0p ); }
     221        long double ato( const char * sptr ) { return strtold( sptr, 0p ); }
     222
     223        float _Complex ato( const char * sptr ) { return strto( sptr, 0p ); }
     224        double _Complex ato( const char * sptr ) { return strto( sptr, 0p ); }
     225        long double _Complex ato( const char * sptr ) { return strto( sptr, 0p ); }
    226226} // distribution
    227227
  • libcfa/src/time.cfa

    ra505021 r8c50aed  
    1010// Created On       : Tue Mar 27 13:33:14 2018
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Feb  4 08:24:18 2020
    13 // Update Count     : 70
     12// Last Modified On : Sun Jan  5 17:27:40 2020
     13// Update Count     : 69
    1414//
    1515
     
    129129} // dd_mm_yy
    130130
    131 size_t strftime( char buf[], size_t size, const char fmt[], Time time ) with( time ) {
     131size_t strftime( char * buf, size_t size, const char * fmt, Time time ) with( time ) {
    132132        time_t s = tn / TIMEGRAN;
    133133        tm tm;
  • libcfa/src/time.hfa

    ra505021 r8c50aed  
    1010// Created On       : Wed Mar 14 23:18:57 2018
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Feb  4 08:24:32 2020
    13 // Update Count     : 654
     12// Last Modified On : Mon Jan  6 12:50:16 2020
     13// Update Count     : 653
    1414//
    1515
     
    191191} // dmy
    192192
    193 size_t strftime( char buf[], size_t size, const char fmt[], Time time );
     193size_t strftime( char * buf, size_t size, const char * fmt, Time time );
    194194
    195195//------------------------- timeval (cont) -------------------------
  • longrun_tests/Makefile.in

    ra505021 r8c50aed  
    502502am__v_GOC_0 = @echo "  GOC     " $@;
    503503am__v_GOC_1 =
    504 AM_V_PY = $(am__v_PY_@AM_V@)
    505 am__v_PY_ = $(am__v_PY_@AM_DEFAULT_V@)
    506 am__v_PY_0 = @echo "  PYTHON  " $@;
    507 am__v_PY_1 =
    508504AM_V_RUST = $(am__v_RUST_@AM_V@)
    509505am__v_RUST_ = $(am__v_RUST_@AM_DEFAULT_V@)
    510 am__v_RUST_0 = @echo "  RUST    " $@;
     506am__v_RUST_0 = @echo "  RUST     " $@;
    511507am__v_RUST_1 =
    512508AM_V_NODEJS = $(am__v_NODEJS_@AM_V@)
    513509am__v_NODEJS_ = $(am__v_NODEJS_@AM_DEFAULT_V@)
    514 am__v_NODEJS_0 = @echo "  NODEJS  " $@;
     510am__v_NODEJS_0 = @echo "  NODEJS     " $@;
    515511am__v_NODEJS_1 =
    516512AM_V_JAVAC = $(am__v_JAVAC_@AM_V@)
  • src/CodeGen/CodeGenerator.cc

    ra505021 r8c50aed  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Feb 16 08:32:48 2020
    13 // Update Count     : 532
     12// Last Modified On : Fri Dec 13 23:13:28 2019
     13// Update Count     : 508
    1414//
    1515#include "CodeGenerator.h"
     
    3939        int CodeGenerator::tabsize = 4;
    4040
    41         // The kinds of statements that would ideally be followed by whitespace.
     41        // the kinds of statements that would ideally be followed by whitespace
    4242        bool wantSpacing( Statement * stmt) {
    4343                return dynamic_cast< IfStmt * >( stmt ) || dynamic_cast< CompoundStmt * >( stmt ) ||
     
    7878        }
    7979
    80         // Using updateLocation at the beginning of a node and endl within a node should become the method of formating.
     80        /* Using updateLocation at the beginning of a node and endl
     81         * within a node should become the method of formating.
     82         */
    8183        void CodeGenerator::updateLocation( CodeLocation const & to ) {
    8284                // skip if linemarks shouldn't appear or if codelocation is unset
     
    9395                } else {
    9496                        output << "\n# " << to.first_line << " \"" << to.filename
    95                                    << "\"\n" << indent;
     97                               << "\"\n" << indent;
    9698                        currentLocation = to;
    9799                }
     
    129131
    130132        void CodeGenerator::genAttributes( list< Attribute * > & attributes ) {
    131                 if ( attributes.empty() ) return;
     133          if ( attributes.empty() ) return;
    132134                output << "__attribute__ ((";
    133135                for ( list< Attribute * >::iterator attr( attributes.begin() );; ) {
     
    138140                                output << ")";
    139141                        } // if
    140                         if ( ++attr == attributes.end() ) break;
     142                  if ( ++attr == attributes.end() ) break;
    141143                        output << ",";                                                          // separator
    142144                } // for
     
    163165                previsit( (BaseSyntaxNode *)node );
    164166                GuardAction( [this, node](){
    165                                 if ( options.printExprTypes && node->result ) {
    166                                         output << " /* " << genType( node->result, "", options ) << " */ ";
    167                                 }
    168                         } );
     167                        if ( options.printExprTypes && node->result ) {
     168                                output << " /* " << genType( node->result, "", options ) << " */ ";
     169                        }
     170                } );
    169171        }
    170172
     
    397399                extension( applicationExpr );
    398400                if ( VariableExpr * varExpr = dynamic_cast< VariableExpr* >( applicationExpr->get_function() ) ) {
    399                         const OperatorInfo * opInfo;
    400                         if ( varExpr->get_var()->get_linkage() == LinkageSpec::Intrinsic && ( opInfo = operatorLookup( varExpr->get_var()->get_name() ) ) ) {
     401                        OperatorInfo opInfo;
     402                        if ( varExpr->get_var()->get_linkage() == LinkageSpec::Intrinsic && operatorLookup( varExpr->get_var()->get_name(), opInfo ) ) {
    401403                                std::list< Expression* >::iterator arg = applicationExpr->get_args().begin();
    402                                 switch ( opInfo->type ) {
     404                                switch ( opInfo.type ) {
    403405                                  case OT_INDEX:
    404406                                        assert( applicationExpr->get_args().size() == 2 );
     
    421423                                                output << "(";
    422424                                                (*arg++)->accept( *visitor );
    423                                                 output << ") /* " << opInfo->inputName << " */";
     425                                                output << ") /* " << opInfo.inputName << " */";
    424426                                        } else if ( applicationExpr->get_args().size() == 2 ) {
    425427                                                // intrinsic two parameter constructors are essentially bitwise assignment
    426428                                                output << "(";
    427429                                                (*arg++)->accept( *visitor );
    428                                                 output << opInfo->symbol;
     430                                                output << opInfo.symbol;
    429431                                                (*arg)->accept( *visitor );
    430                                                 output << ") /* " << opInfo->inputName << " */";
     432                                                output << ") /* " << opInfo.inputName << " */";
    431433                                        } else {
    432434                                                // no constructors with 0 or more than 2 parameters
     
    439441                                        assert( applicationExpr->get_args().size() == 1 );
    440442                                        output << "(";
    441                                         output << opInfo->symbol;
     443                                        output << opInfo.symbol;
    442444                                        (*arg)->accept( *visitor );
    443445                                        output << ")";
     
    448450                                        assert( applicationExpr->get_args().size() == 1 );
    449451                                        (*arg)->accept( *visitor );
    450                                         output << opInfo->symbol;
     452                                        output << opInfo.symbol;
    451453                                        break;
    452454
     
    457459                                        output << "(";
    458460                                        (*arg++)->accept( *visitor );
    459                                         output << opInfo->symbol;
     461                                        output << opInfo.symbol;
    460462                                        (*arg)->accept( *visitor );
    461463                                        output << ")";
     
    484486                extension( untypedExpr );
    485487                if ( NameExpr * nameExpr = dynamic_cast< NameExpr* >( untypedExpr->function ) ) {
    486                         const OperatorInfo * opInfo = operatorLookup( nameExpr->name );
    487                         if ( opInfo ) {
     488                        OperatorInfo opInfo;
     489                        if ( operatorLookup( nameExpr->name, opInfo ) ) {
    488490                                std::list< Expression* >::iterator arg = untypedExpr->args.begin();
    489                                 switch ( opInfo->type ) {
     491                                switch ( opInfo.type ) {
    490492                                  case OT_INDEX:
    491493                                        assert( untypedExpr->args.size() == 2 );
     
    506508                                                output << "(";
    507509                                                (*arg++)->accept( *visitor );
    508                                                 output << ") /* " << opInfo->inputName << " */";
     510                                                output << ") /* " << opInfo.inputName << " */";
    509511                                        } else if ( untypedExpr->get_args().size() == 2 ) {
    510512                                                // intrinsic two parameter constructors are essentially bitwise assignment
    511513                                                output << "(";
    512514                                                (*arg++)->accept( *visitor );
    513                                                 output << opInfo->symbol;
     515                                                output << opInfo.symbol;
    514516                                                (*arg)->accept( *visitor );
    515                                                 output << ") /* " << opInfo->inputName << " */";
     517                                                output << ") /* " << opInfo.inputName << " */";
    516518                                        } else {
    517519                                                // no constructors with 0 or more than 2 parameters
     
    519521                                                output << "(";
    520522                                                (*arg++)->accept( *visitor );
    521                                                 output << opInfo->symbol << "{ ";
     523                                                output << opInfo.symbol << "{ ";
    522524                                                genCommaList( arg, untypedExpr->args.end() );
    523                                                 output << "}) /* " << opInfo->inputName << " */";
     525                                                output << "}) /* " << opInfo.inputName << " */";
    524526                                        } // if
    525527                                        break;
     
    530532                                        assert( untypedExpr->args.size() == 1 );
    531533                                        output << "(";
    532                                         output << opInfo->symbol;
     534                                        output << opInfo.symbol;
    533535                                        (*arg)->accept( *visitor );
    534536                                        output << ")";
     
    539541                                        assert( untypedExpr->args.size() == 1 );
    540542                                        (*arg)->accept( *visitor );
    541                                         output << opInfo->symbol;
     543                                        output << opInfo.symbol;
    542544                                        break;
    543545
     
    547549                                        output << "(";
    548550                                        (*arg++)->accept( *visitor );
    549                                         output << opInfo->symbol;
     551                                        output << opInfo.symbol;
    550552                                        (*arg)->accept( *visitor );
    551553                                        output << ")";
     
    579581        void CodeGenerator::postvisit( NameExpr * nameExpr ) {
    580582                extension( nameExpr );
    581                 const OperatorInfo * opInfo = operatorLookup( nameExpr->name );
    582                 if ( opInfo ) {
    583                         if ( opInfo->type == OT_CONSTANT ) {
    584                                 output << opInfo->symbol;
     583                OperatorInfo opInfo;
     584                if ( operatorLookup( nameExpr->name, opInfo ) ) {
     585                        if ( opInfo.type == OT_CONSTANT ) {
     586                                output << opInfo.symbol;
    585587                        } else {
    586                                 output << opInfo->outputName;
     588                                output << opInfo.outputName;
    587589                        }
    588590                } else {
     
    652654        void CodeGenerator::postvisit( VariableExpr * variableExpr ) {
    653655                extension( variableExpr );
    654                 const OperatorInfo * opInfo;
    655                 if ( variableExpr->get_var()->get_linkage() == LinkageSpec::Intrinsic && (opInfo = operatorLookup( variableExpr->get_var()->get_name() )) && opInfo->type == OT_CONSTANT ) {
    656                         output << opInfo->symbol;
     656                OperatorInfo opInfo;
     657                if ( variableExpr->get_var()->get_linkage() == LinkageSpec::Intrinsic && operatorLookup( variableExpr->get_var()->get_name(), opInfo ) && opInfo.type == OT_CONSTANT ) {
     658                        output << opInfo.symbol;
    657659                } else {
    658660                        output << mangleName( variableExpr->get_var() );
     
    10091011                  case BranchStmt::FallThroughDefault:
    10101012                        assertf( ! options.genC, "fallthru should not reach code generation." );
    1011                         output << "fallthru";
     1013                  output << "fallthru";
    10121014                        break;
    10131015                } // switch
     
    10331035
    10341036                output << ((throwStmt->get_kind() == ThrowStmt::Terminate) ?
    1035                                    "throw" : "throwResume");
     1037                           "throw" : "throwResume");
    10361038                if (throwStmt->get_expr()) {
    10371039                        output << " ";
     
    10481050
    10491051                output << ((stmt->get_kind() == CatchStmt::Terminate) ?
    1050                                    "catch" : "catchResume");
     1052                "catch" : "catchResume");
    10511053                output << "( ";
    10521054                stmt->decl->accept( *visitor );
     
    11851187
    11861188        std::string genName( DeclarationWithType * decl ) {
    1187                 const OperatorInfo * opInfo = operatorLookup( decl->get_name() );
    1188                 if ( opInfo ) {
    1189                         return opInfo->outputName;
     1189                CodeGen::OperatorInfo opInfo;
     1190                if ( operatorLookup( decl->get_name(), opInfo ) ) {
     1191                        return opInfo.outputName;
    11901192                } else {
    11911193                        return decl->get_name();
  • src/CodeGen/CodeGenerator.h

    ra505021 r8c50aed  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Feb 16 03:58:31 2020
    13 // Update Count     : 62
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Tue Apr 30 12:01:00 2019
     13// Update Count     : 57
    1414//
    1515
     
    2929namespace CodeGen {
    3030        struct CodeGenerator : public WithShortCircuiting, public WithGuards, public WithVisitorRef<CodeGenerator> {
    31                 static int tabsize;
     31          static int tabsize;
    3232
    3333                CodeGenerator( std::ostream &os, bool pretty = false, bool genC = false, bool lineMarks = false, bool printExprTypes = false );
     
    104104                void postvisit( AsmStmt * );
    105105                void postvisit( DirectiveStmt * );
    106                 void postvisit( AsmDecl * );                                    // special: statement in declaration context
     106                void postvisit( AsmDecl * );                            // special: statement in declaration context
    107107                void postvisit( IfStmt * );
    108108                void postvisit( SwitchStmt * );
     
    147147                LabelPrinter printLabels;
    148148                Options options;
    149           public:
     149        public:
    150150                LineEnder endl;
    151           private:
     151        private:
    152152
    153153                CodeLocation currentLocation;
     
    162162        template< class Iterator >
    163163        void CodeGenerator::genCommaList( Iterator begin, Iterator end ) {
    164                 if ( begin == end ) return;
     164          if ( begin == end ) return;
    165165                for ( ;; ) {
    166166                        (*begin++)->accept( *visitor );
    167                         if ( begin == end ) break;
     167                  if ( begin == end ) break;
    168168                        output << ", ";                                                         // separator
    169169                } // for
  • src/CodeGen/FixMain.h

    ra505021 r8c50aed  
    1010// Created On       : Thr Jan 12 14:11:09 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Feb 16 03:24:32 2020
    13 // Update Count     : 5
     12// Last Modified On : Fri Dec 13 23:12:21 2019
     13// Update Count     : 3
    1414//
    1515
     
    4242                static std::unique_ptr<FunctionDecl> main_signature;
    4343        };
    44 } // namespace CodeGen
     44};
  • src/CodeGen/GenType.h

    ra505021 r8c50aed  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Feb 16 04:11:40 2020
    13 // Update Count     : 5
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Tue Apr 30 11:47:00 2019
     13// Update Count     : 3
    1414//
    1515
     
    2525        std::string genType( Type *type, const std::string &baseString, const Options &options );
    2626        std::string genType( Type *type, const std::string &baseString, bool pretty = false, bool genC = false, bool lineMarks = false );
    27         std::string genPrettyType( Type * type, const std::string & baseString );
     27  std::string genPrettyType( Type * type, const std::string & baseString );
    2828} // namespace CodeGen
    2929
  • src/CodeGen/Generate.cc

    ra505021 r8c50aed  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Feb 16 03:01:51 2020
    13 // Update Count     : 9
     12// Last Modified On : Fri Dec 13 23:38:56 2019
     13// Update Count     : 8
    1414//
    1515#include "Generate.h"
     
    6464        void generate( BaseSyntaxNode * node, std::ostream & os ) {
    6565                if ( Type * type = dynamic_cast< Type * >( node ) ) {
    66                         os << genPrettyType( type, "" );
     66                        os << CodeGen::genPrettyType( type, "" );
    6767                } else {
    6868                        PassVisitor<CodeGenerator> cgv( os, true, false, false, false );
  • src/CodeGen/OperatorTable.cc

    ra505021 r8c50aed  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Feb 18 15:55:01 2020
    13 // Update Count     : 55
     12// Last Modified On : Sat Jul 15 17:12:22 2017
     13// Update Count     : 15
    1414//
    1515
     
    1717#include <map>        // for map, _Rb_tree_const_iterator, map<>::const_iterator
    1818#include <utility>    // for pair
    19 using namespace std;
    2019
    2120#include "OperatorTable.h"
     
    2322
    2423namespace CodeGen {
    25         const OperatorInfo CodeGen::tableValues[] = {
    26                 // inputName symbol   outputName                     friendlyName                  type
    27                 {       "?[?]",   "",     "_operator_index",             "Index",                      OT_INDEX          },
    28                 {       "?{}",    "=",    "_constructor",                "Constructor",                OT_CTOR           },
    29                 {       "^?{}",   "",     "_destructor",                 "Destructor",                 OT_DTOR           },
    30                 {       "?()",    "",     "_operator_call",              "Call Operator",              OT_CALL           },
    31                 {       "?++",    "++",   "_operator_postincr",          "Postfix Increment",          OT_POSTFIXASSIGN  },
    32                 {       "?--",    "--",   "_operator_postdecr",          "Postfix Decrement",          OT_POSTFIXASSIGN  },
    33                 {       "*?",     "*",    "_operator_deref",             "Dereference",                OT_PREFIX         },
    34                 {       "+?",     "+",    "_operator_unaryplus",         "Plus",                       OT_PREFIX         },
    35                 {       "-?",     "-",    "_operator_unaryminus",        "Minus",                      OT_PREFIX         },
    36                 {       "~?",     "~",    "_operator_bitnot",            "Bitwise Not",                OT_PREFIX         },
    37                 {       "!?",     "!",    "_operator_lognot",            "Logical Not",                OT_PREFIX         },
    38                 {       "++?",    "++",   "_operator_preincr",           "Prefix Increment",           OT_PREFIXASSIGN   },
    39                 {       "--?",    "--",   "_operator_predecr",           "Prefix Decrement",           OT_PREFIXASSIGN   },
    40                 {       "?\\?",   "\\",   "_operator_exponential",       "Exponentiation",             OT_INFIX          },
    41                 {       "?*?",    "*",    "_operator_multiply",          "Multiplication",             OT_INFIX          },
    42                 {       "?/?",    "/",    "_operator_divide",            "Division",                   OT_INFIX          },
    43                 {       "?%?",    "%",    "_operator_modulus",           "Modulo",                     OT_INFIX          },
    44                 {       "?+?",    "+",    "_operator_add",               "Addition",                   OT_INFIX          },
    45                 {       "?-?",    "-",    "_operator_subtract",          "Substraction",               OT_INFIX          },
    46                 {       "?<<?",   "<<",   "_operator_shiftleft",         "Shift Left",                 OT_INFIX          },
    47                 {       "?>>?",   ">>",   "_operator_shiftright",        "Shift Right",                OT_INFIX          },
    48                 {       "?<?",    "<",    "_operator_less",              "Less-than",                  OT_INFIX          },
    49                 {       "?>?",    ">",    "_operator_greater",           "Greater-than",               OT_INFIX          },
    50                 {       "?<=?",   "<=",   "_operator_lessequal",         "Less-than-or-Equal",         OT_INFIX          },
    51                 {       "?>=?",   ">=",   "_operator_greaterequal",      "Greater-than-or-Equal",      OT_INFIX          },
    52                 {       "?==?",   "==",   "_operator_equal",             "Equality",                   OT_INFIX          },
    53                 {       "?!=?",   "!=",   "_operator_notequal",          "Not-Equal",                  OT_INFIX          },
    54                 {       "?&?",    "&",    "_operator_bitand",            "Bitwise And",                OT_INFIX          },
    55                 {       "?^?",    "^",    "_operator_bitxor",            "Bitwise Xor",                OT_INFIX          },
    56                 {       "?|?",    "|",    "_operator_bitor",             "Bitwise Or",                 OT_INFIX          },
    57                 {       "?=?",    "=",    "_operator_assign",            "Assignment",                 OT_INFIXASSIGN    },
    58                 {       "?\\=?",  "\\=",  "_operator_expassign",         "Exponentiation Assignment",  OT_INFIXASSIGN    },
    59                 {       "?*=?",   "*=",   "_operator_multassign",        "Multiplication Assignment",  OT_INFIXASSIGN    },
    60                 {       "?/=?",   "/=",   "_operator_divassign",         "Division Assignment",        OT_INFIXASSIGN    },
    61                 {       "?%=?",   "%=",   "_operator_modassign",         "Modulo Assignment",          OT_INFIXASSIGN    },
    62                 {       "?+=?",   "+=",   "_operator_addassign",         "Addition Assignment",        OT_INFIXASSIGN    },
    63                 {       "?-=?",   "-=",   "_operator_subassign",         "Substrction Assignment",     OT_INFIXASSIGN    },
    64                 {       "?<<=?",  "<<=",  "_operator_shiftleftassign",   "Shift Left Assignment",      OT_INFIXASSIGN    },
    65                 {       "?>>=?",  ">>=",  "_operator_shiftrightassign",  "Shift Right Assignment",     OT_INFIXASSIGN    },
    66                 {       "?&=?",   "&=",   "_operator_bitandassign",      "Bitwise And Assignment",     OT_INFIXASSIGN    },
    67                 {       "?^=?",   "^=",   "_operator_bitxorassign",      "Bitwise Xor Assignment",     OT_INFIXASSIGN    },
    68                 {       "?|=?",   "|=",   "_operator_bitorassign",       "Bitwise Or Assignment",      OT_INFIXASSIGN    },
    69         }; // tableValues
     24        namespace {
     25                const OperatorInfo tableValues[] = {
     26                        {       "?[?]",         "",             "_operator_index",                              OT_INDEX                        },
     27                        {       "?{}",          "=",    "_constructor",                                 OT_CTOR                         },
     28                        {       "^?{}",         "",             "_destructor",                                  OT_DTOR                         },
     29                        {       "?()",          "",             "_operator_call",                               OT_CALL                         },
     30                        {       "?++",          "++",   "_operator_postincr",                   OT_POSTFIXASSIGN        },
     31                        {       "?--",          "--",   "_operator_postdecr",                   OT_POSTFIXASSIGN        },
     32                        {       "*?",           "*",    "_operator_deref",                              OT_PREFIX                       },
     33                        {       "+?",           "+",    "_operator_unaryplus",                  OT_PREFIX                       },
     34                        {       "-?",           "-",    "_operator_unaryminus",                 OT_PREFIX                       },
     35                        {       "~?",           "~",    "_operator_bitnot",                             OT_PREFIX                       },
     36                        {       "!?",           "!",    "_operator_lognot",                             OT_PREFIX                       },
     37                        {       "++?",          "++",   "_operator_preincr",                    OT_PREFIXASSIGN         },
     38                        {       "--?",          "--",   "_operator_predecr",                    OT_PREFIXASSIGN         },
     39                        {       "?\\?",         "\\",   "_operator_exponential",                OT_INFIX                        },
     40                        {       "?*?",          "*",    "_operator_multiply",                   OT_INFIX                        },
     41                        {       "?/?",          "/",    "_operator_divide",                             OT_INFIX                        },
     42                        {       "?%?",          "%",    "_operator_modulus",                    OT_INFIX                        },
     43                        {       "?+?",          "+",    "_operator_add",                                OT_INFIX                        },
     44                        {       "?-?",          "-",    "_operator_subtract",                   OT_INFIX                        },
     45                        {       "?<<?",         "<<",   "_operator_shiftleft",                  OT_INFIX                        },
     46                        {       "?>>?",         ">>",   "_operator_shiftright",                 OT_INFIX                        },
     47                        {       "?<?",          "<",    "_operator_less",                               OT_INFIX                        },
     48                        {       "?>?",          ">",    "_operator_greater",                    OT_INFIX                        },
     49                        {       "?<=?",         "<=",   "_operator_lessequal",                  OT_INFIX                        },
     50                        {       "?>=?",         ">=",   "_operator_greaterequal",               OT_INFIX                        },
     51                        {       "?==?",         "==",   "_operator_equal",                              OT_INFIX                        },
     52                        {       "?!=?",         "!=",   "_operator_notequal",                   OT_INFIX                        },
     53                        {       "?&?",          "&",    "_operator_bitand",                             OT_INFIX                        },
     54                        {       "?^?",          "^",    "_operator_bitxor",                             OT_INFIX                        },
     55                        {       "?|?",          "|",    "_operator_bitor",                              OT_INFIX                        },
     56                        {       "?=?",          "=",    "_operator_assign",                             OT_INFIXASSIGN          },
     57                        {       "?\\=?",        "\\=",  "_operator_expassign",                  OT_INFIXASSIGN          },
     58                        {       "?*=?",         "*=",   "_operator_multassign",                 OT_INFIXASSIGN          },
     59                        {       "?/=?",         "/=",   "_operator_divassign",                  OT_INFIXASSIGN          },
     60                        {       "?%=?",         "%=",   "_operator_modassign",                  OT_INFIXASSIGN          },
     61                        {       "?+=?",         "+=",   "_operator_addassign",                  OT_INFIXASSIGN          },
     62                        {       "?-=?",         "-=",   "_operator_subassign",                  OT_INFIXASSIGN          },
     63                        {       "?<<=?",        "<<=",  "_operator_shiftleftassign",    OT_INFIXASSIGN          },
     64                        {       "?>>=?",        ">>=",  "_operator_shiftrightassign",   OT_INFIXASSIGN          },
     65                        {       "?&=?",         "&=",   "_operator_bitandassign",               OT_INFIXASSIGN          },
     66                        {       "?^=?",         "^=",   "_operator_bitxorassign",               OT_INFIXASSIGN          },
     67                        {       "?|=?",         "|=",   "_operator_bitorassign",                OT_INFIXASSIGN          },
     68                };
    7069
    71         std::map< std::string, OperatorInfo > CodeGen::table;
     70                const int numOps = sizeof( tableValues ) / sizeof( OperatorInfo );
    7271
    73         CodeGen::CodeGen() {
    74                 enum { numOps = sizeof( tableValues ) / sizeof( OperatorInfo ) };
    75                 for ( int i = 0; i < numOps; i += 1 ) {
    76                         table[ tableValues[i].inputName ] = tableValues[i];
    77                 } // for
     72                std::map< std::string, OperatorInfo > table;
     73
     74                void initialize() {
     75                        for ( int i = 0; i < numOps; ++i ) {
     76                                table[ tableValues[i].inputName ] = tableValues[i];
     77                        } // for
     78                }
     79        } // namespace
     80
     81        bool operatorLookup( const std::string & funcName, OperatorInfo & info ) {
     82                static bool init = false;
     83                if ( ! init ) {
     84                        initialize();
     85                } // if
     86
     87                std::map< std::string, OperatorInfo >::const_iterator i = table.find( funcName );
     88                if ( i == table.end() ) {
     89                        if ( isPrefix( funcName, "?`" ) ) {
     90                                // handle literal suffixes, which are user-defined postfix operators
     91                                info.inputName = funcName;
     92                                info.symbol = funcName.substr(2);
     93                                info.outputName = toString( "__operator_literal_", info.symbol );
     94                                info.type = OT_POSTFIX;
     95                                return true;
     96                        }
     97                        return false;
     98                } else {
     99                        info = i->second;
     100                        return true;
     101                } // if
    78102        }
    79103
    80         const OperatorInfo * operatorLookup( const string & funcName ) {
    81                 if ( funcName.find_first_of( "?^*+-!", 0, 1 ) == string::npos ) return nullptr; // prefilter
    82                 const OperatorInfo * ret = &CodeGen::table.find( funcName )->second; // must be in the table
    83                 assert( ret );
    84                 return ret;
     104        bool isOperator( const std::string & funcName ) {
     105                OperatorInfo info;
     106                return operatorLookup( funcName, info );
    85107        }
    86108
    87         bool isOperator( const string & funcName ) {
    88                 return operatorLookup( funcName ) != nullptr;
    89         }
    90 
    91         string operatorFriendlyName( const string & funcName ) {
    92                 const OperatorInfo * info = operatorLookup( funcName );
    93                 if ( info ) return info->friendlyName;
    94                 return "";
    95         }
    96 
    97         bool isConstructor( const string & funcName ) {
    98                 const OperatorInfo * info = operatorLookup( funcName );
    99                 if ( info ) return info->type == OT_CTOR;
     109        /// determines if a given function name is one of the operator types between [begin, end)
     110        template<typename Iterator>
     111        bool isOperatorType( const std::string & funcName, Iterator begin, Iterator end ) {
     112                OperatorInfo info;
     113                if ( operatorLookup( funcName, info ) ) {
     114                        return std::find( begin, end, info.type ) != end;
     115                }
    100116                return false;
    101117        }
    102118
    103         bool isDestructor( const string & funcName ) {
    104                 const OperatorInfo * info = operatorLookup( funcName );
    105                 if ( info ) return info->type == OT_DTOR;
    106                 return false;
     119        bool isConstructor( const std::string & funcName ) {
     120                static OperatorType types[] = { OT_CTOR };
     121                return isOperatorType( funcName, std::begin(types), std::end(types) );
    107122        }
    108123
    109         bool isCtorDtor( const string & funcName ) {
    110                 const OperatorInfo * info = operatorLookup( funcName );
    111                 if ( info ) return info->type <= OT_CONSTRUCTOR;
    112                 return false;
     124        bool isDestructor( const std::string & funcName ) {
     125                static OperatorType types[] = { OT_DTOR };
     126                return isOperatorType( funcName, std::begin(types), std::end(types) );
    113127        }
    114128
    115         bool isAssignment( const string & funcName ) {
    116                 const OperatorInfo * info = operatorLookup( funcName );
    117                 if ( info ) return info->type > OT_CONSTRUCTOR && info->type <= OT_ASSIGNMENT;
    118                 return false;
     129        bool isAssignment( const std::string & funcName ) {
     130                static OperatorType types[] = { OT_PREFIXASSIGN, OT_POSTFIXASSIGN, OT_INFIXASSIGN };
     131                return isOperatorType( funcName, std::begin(types), std::end(types) );
    119132        }
    120133
    121         bool isCtorDtorAssign( const string & funcName ) {
    122                 const OperatorInfo * info = operatorLookup( funcName );
    123                 if ( info ) return info->type <= OT_ASSIGNMENT;
    124                 return false;
     134        bool isCtorDtor( const std::string & funcName ) {
     135                static OperatorType types[] = { OT_CTOR, OT_DTOR };
     136                return isOperatorType( funcName, std::begin(types), std::end(types) );
    125137        }
    126138
    127         CodeGen codegen;                                                                        // initialize singleton package
     139        bool isCtorDtorAssign( const std::string & funcName ) {
     140                static OperatorType types[] = { OT_CTOR, OT_DTOR, OT_PREFIXASSIGN, OT_POSTFIXASSIGN, OT_INFIXASSIGN };
     141                return isOperatorType( funcName, std::begin(types), std::end(types) );
     142        }
    128143} // namespace CodeGen
    129144
    130145// Local Variables: //
    131146// tab-width: 4 //
     147// mode: c++ //
     148// compile-command: "make install" //
    132149// End: //
  • src/CodeGen/OperatorTable.h

    ra505021 r8c50aed  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Feb 16 08:13:34 2020
    13 // Update Count     : 26
     12// Last Modified On : Fri Jul 21 22:17:11 2017
     13// Update Count     : 6
    1414//
    1515
     
    1717
    1818#include <string>
    19 #include <map>
    2019
    2120namespace CodeGen {
    2221        enum OperatorType {
     22                OT_INDEX,
    2323                OT_CTOR,
    2424                OT_DTOR,
    25                 OT_CONSTRUCTOR = OT_DTOR,
     25                OT_CALL,
     26                OT_PREFIX,
     27                OT_POSTFIX,
     28                OT_INFIX,
    2629                OT_PREFIXASSIGN,
    2730                OT_POSTFIXASSIGN,
    2831                OT_INFIXASSIGN,
    29                 OT_ASSIGNMENT = OT_INFIXASSIGN,
    30                 OT_CALL,
    31                 OT_PREFIX,
    32                 OT_INFIX,
    33                 OT_POSTFIX,
    34                 OT_INDEX,
    3532                OT_LABELADDRESS,
    3633                OT_CONSTANT
     
    4138                std::string symbol;
    4239                std::string outputName;
    43                 std::string friendlyName;
    4440                OperatorType type;
    4541        };
    4642
    47         class CodeGen {
    48                 friend const OperatorInfo * operatorLookup( const std::string & funcName );
    49 
    50                 static const OperatorInfo tableValues[];
    51                 static std::map< std::string, OperatorInfo > table;
    52           public:
    53                 CodeGen();
    54         }; // CodeGen
    55 
    5643        bool isOperator( const std::string & funcName );
    57         const OperatorInfo * operatorLookup( const std::string & funcName );
    58         std::string operatorFriendlyName( const std::string & funcName );
     44        bool operatorLookup( const std::string & funcName, OperatorInfo & info );
    5945
    6046        bool isConstructor( const std::string & );
  • src/CodeGen/Options.h

    ra505021 r8c50aed  
    99// Author           : Andrew Beach
    1010// Created On       : Tue Apr 30 11:36:00 2019
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Feb 15 18:37:06 2020
    13 // Update Count     : 3
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Thr May  2 10:45:00 2019
     13// Update Count     : 2
    1414//
    1515
    1616#pragma once
    1717
    18 struct Options {
    19         // External Options: Same thoughout a pass.
    20         bool pretty;
    21         bool genC;
    22         bool lineMarks;
    23         bool printExprTypes;
     18namespace CodeGen {
     19        struct Options {
     20                // External Options: Same thoughout a pass.
     21                bool pretty;
     22                bool genC;
     23                bool lineMarks;
     24                bool printExprTypes;
    2425
    25         // Internal Options: Changed on some recurisive calls.
    26         bool anonymousUnused = false;
     26                // Internal Options: Changed on some recurisive calls.
     27                bool anonymousUnused = false;
    2728
    28         Options(bool pretty, bool genC, bool lineMarks, bool printExprTypes) :
    29                 pretty(pretty), genC(genC), lineMarks(lineMarks), printExprTypes(printExprTypes)
     29                Options(bool pretty, bool genC, bool lineMarks, bool printExprTypes) :
     30                        pretty(pretty), genC(genC), lineMarks(lineMarks), printExprTypes(printExprTypes)
    3031                {}
    31 };
     32        };
     33} // namespace CodeGen
    3234
    3335// Local Variables: //
  • src/CodeTools/ResolvProtoDump.cc

    ra505021 r8c50aed  
    99// Author           : Aaron Moss
    1010// Created On       : Tue Sep 11 09:04:00 2018
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Feb 15 13:50:11 2020
    13 // Update Count     : 3
     11// Last Modified By : Aaron Moss
     12// Last Modified On : Tue Sep 11 09:04:00 2018
     13// Update Count     : 1
    1414//
    1515
     
    182182
    183183                        // replace operator names
    184                         const CodeGen::OperatorInfo * opInfo = CodeGen::operatorLookup( name );
    185                         if ( opInfo ) {
     184                        CodeGen::OperatorInfo info;
     185                        if ( CodeGen::operatorLookup( name, info ) ) {
    186186                                ss << new_prefix(pre, "");
    187                                 op_name( opInfo->outputName, ss );
     187                                op_name( info.outputName, ss );
    188188                                return;
    189189                        }
  • src/Common/PassVisitor.impl.h

    ra505021 r8c50aed  
    33023302        VISIT_START( node );
    33033303
    3304         indexerAddUnion( node->name );
     3304        indexerAddStruct( node->name );
    33053305
    33063306        {
     
    33173317        VISIT_START( node );
    33183318
    3319         indexerAddUnion( node->name );
     3319        indexerAddStruct( node->name );
    33203320
    33213321        {
     
    33323332        MUTATE_START( node );
    33333333
    3334         indexerAddUnion( node->name );
     3334        indexerAddStruct( node->name );
    33353335
    33363336        {
  • src/Common/SemanticError.h

    ra505021 r8c50aed  
    4949struct WarningData {
    5050        const char * const name;
     51        const char * const message;
    5152        const Severity default_severity;
    52         const char * const message;
    5353};
    5454
    5555constexpr WarningData WarningFormats[] = {
    56         {"self-assign"            , Severity::Warn    , "self assignment of expression: %s"                          },
    57         {"reference-conversion"   , Severity::Warn    , "rvalue to reference conversion of rvalue: %s"               },
    58         {"qualifiers-zero_t-one_t", Severity::Warn    , "questionable use of type qualifier %s with %s"              },
    59         {"aggregate-forward-decl" , Severity::Warn    , "forward declaration of nested aggregate: %s"                },
    60         {"superfluous-decl"       , Severity::Warn    , "declaration does not allocate storage: %s"                  },
    61         {"gcc-attributes"         , Severity::Warn    , "invalid attribute: %s"                                      },
    62         {"c++-like-copy"          , Severity::Warn    , "Constructor from reference is not a valid copy constructor" },
     56        {"self-assign"            , "self assignment of expression: %s"            , Severity::Warn},
     57        {"reference-conversion"   , "rvalue to reference conversion of rvalue: %s" , Severity::Warn},
     58        {"qualifiers-zero_t-one_t", "questionable use of type qualifier %s with %s", Severity::Warn},
     59        {"aggregate-forward-decl" , "forward declaration of nested aggregate: %s"  , Severity::Warn},
     60        {"superfluous-decl"       , "declaration does not allocate storage: %s"    , Severity::Warn},
     61        {"gcc-attributes"         , "invalid attribute: %s"                        , Severity::Warn},
    6362};
    6463
     
    7069        SuperfluousDecl,
    7170        GccAttributes,
    72         CppCopy,
    7371        NUMBER_OF_WARNINGS, // This MUST be the last warning
    7472};
  • src/Common/utility.h

    ra505021 r8c50aed  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Feb 11 13:00:36 2020
    13 // Update Count     : 50
     12// Last Modified On : Wed Jul 24 14:28:19 2019
     13// Update Count     : 41
    1414//
    1515
     
    2929#include <utility>
    3030#include <vector>
    31 #include <cstring>                                                                              // memcmp
    3231
    3332#include "Common/Indenter.h"
     
    265264}
    266265
    267 // determines if pref is a prefix of str
    268 static inline bool isPrefix( const std::string & str, const std::string & pref, unsigned int start = 0 ) {
     266/// determines if `pref` is a prefix of `str`
     267static inline bool isPrefix( const std::string & str, const std::string & pref ) {
    269268        if ( pref.size() > str.size() ) return false;
    270     return 0 == memcmp( str.c_str() + start, pref.c_str(), pref.size() );
    271         // return prefix == full.substr(0, prefix.size()); // for future, requires c++17
     269        auto its = std::mismatch( pref.begin(), pref.end(), str.begin() );
     270        return its.first == pref.end();
    272271}
    273272
  • src/ControlStruct/Mutate.cc

    ra505021 r8c50aed  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Feb 16 03:22:07 2020
    13 // Update Count     : 10
     12// Last Modified On : Thu Aug  4 11:39:08 2016
     13// Update Count     : 9
    1414//
    1515
     
    3737                mutateAll( translationUnit, formut );
    3838        }
    39 } // namespace ControlStruct
     39} // namespace CodeGen
    4040
    4141// Local Variables: //
  • src/InitTweak/FixInit.cc

    ra505021 r8c50aed  
    1010// Created On       : Wed Jan 13 16:29:30 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Feb 16 04:17:07 2020
    13 // Update Count     : 82
     12// Last Modified On : Fri Dec 13 23:41:27 2019
     13// Update Count     : 77
    1414//
    1515#include "FixInit.h"
     
    745745                }
    746746
    747                 // to prevent warnings ('_unq0' may be used uninitialized in this function),
     747                // to prevent warnings (‘_unq0’ may be used uninitialized in this function),
    748748                // insert an appropriate zero initializer for UniqueExpr temporaries.
    749749                Initializer * makeInit( Type * t ) {
  • src/InitTweak/FixInit.h

    ra505021 r8c50aed  
    1010// Created On       : Wed Jan 13 16:29:30 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Feb 16 07:54:50 2020
    13 // Update Count     : 8
     12// Last Modified On : Sat Jul 22 09:31:06 2017
     13// Update Count     : 6
    1414//
    1515
     
    2222
    2323namespace InitTweak {
    24         /// replace constructor initializers with expression statements and unwrap basic C-style initializers
     24  /// replace constructor initializers with expression statements
     25  /// and unwrap basic C-style initializers
    2526        void fix( std::list< Declaration * > & translationUnit, bool inLibrary );
    2627} // namespace
  • src/MakeLibCfa.cc

    ra505021 r8c50aed  
    1010// Created On       : Sat May 16 10:33:33 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Feb 16 03:49:49 2020
    13 // Update Count     : 45
     12// Last Modified On : Fri Dec 13 23:41:40 2019
     13// Update Count     : 42
    1414//
    1515
     
    9696
    9797                        FunctionDecl *funcDecl = origFuncDecl->clone();
    98                         const CodeGen::OperatorInfo * opInfo;
    99                         opInfo = CodeGen::operatorLookup( funcDecl->get_name() );
    100                         assert( opInfo );
     98                        CodeGen::OperatorInfo opInfo;
     99                        bool lookResult = CodeGen::operatorLookup( funcDecl->get_name(), opInfo );
     100                        assert( lookResult );
    101101                        assert( ! funcDecl->get_statements() );
    102102                        // build a recursive call - this is okay, as the call will actually be codegen'd using operator syntax
     
    120120
    121121                        Statement * stmt = nullptr;
    122                         switch ( opInfo->type ) {
     122                        switch ( opInfo.type ) {
    123123                          case CodeGen::OT_INDEX:
    124124                          case CodeGen::OT_CALL:
  • src/Parser/ParseNode.h

    ra505021 r8c50aed  
    1010// Created On       : Sat May 16 13:28:16 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Feb  7 17:56:02 2020
    13 // Update Count     : 891
     12// Last Modified On : Mon Dec 16 07:46:01 2019
     13// Update Count     : 888
    1414//
    1515
     
    449449                                * out++ = result;
    450450                        } else {
    451                                 SemanticError( cur->location, "type specifier declaration in forall clause is currently unimplemented." );
     451                                assertf(false, "buildList unknown type");
    452452                        } // if
    453453                } catch( SemanticErrorException & e ) {
  • src/Parser/ParserTypes.h

    ra505021 r8c50aed  
    1010// Created On       : Sat Sep 22 08:58:10 2001
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Feb 15 11:04:40 2020
    13 // Update Count     : 351
     12// Last Modified On : Sat Jul 22 09:33:28 2017
     13// Update Count     : 350
    1414//
    1515
     
    2727// current location in the input
    2828extern int yylineno;
    29 extern char * yyfilename;
     29extern char *yyfilename;
    3030
    3131struct Location {
    32     char * file;
     32    char *file;
    3333    int line;
    3434}; // Location
    3535
    3636struct Token {
    37     std::string * str;                                                                  // must be pointer as used in union
     37    std::string *str;                                                                   // must be pointer as used in union
    3838    Location loc;
    3939
  • src/Parser/TypedefTable.cc

    ra505021 r8c50aed  
    1010// Created On       : Sat May 16 15:20:13 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Feb 15 08:06:36 2020
    13 // Update Count     : 259
     12// Last Modified On : Wed Jul 25 15:32:35 2018
     13// Update Count     : 258
    1414//
    1515
     
    4747} // TypedefTable::~TypedefTable
    4848
    49 bool TypedefTable::exists( const string & identifier ) const {
     49bool TypedefTable::exists( const string & identifier ) {
    5050        return kindTable.find( identifier ) != kindTable.end();
    5151} // TypedefTable::exists
    5252
    53 bool TypedefTable::existsCurr( const string & identifier ) const {
     53bool TypedefTable::existsCurr( const string & identifier ) {
    5454        return kindTable.findAt( kindTable.currentScope() - 1, identifier ) != kindTable.end();
    5555} // TypedefTable::exists
  • src/Parser/TypedefTable.h

    ra505021 r8c50aed  
    1010// Created On       : Sat May 16 15:24:36 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Feb 15 08:06:37 2020
    13 // Update Count     : 117
     12// Last Modified On : Wed Jul 25 15:33:55 2018
     13// Update Count     : 114
    1414//
    1515
     
    3030        ~TypedefTable();
    3131
    32         bool exists( const std::string & identifier ) const;
    33         bool existsCurr( const std::string & identifier ) const;
     32        bool exists( const std::string & identifier );
     33        bool existsCurr( const std::string & identifier );
    3434        int isKind( const std::string & identifier ) const;
    3535        void makeTypedef( const std::string & name, int kind = TYPEDEFname );
  • src/Parser/lex.ll

    ra505021 r8c50aed  
    1010 * Created On       : Sat Sep 22 08:58:10 2001
    1111 * Last Modified By : Peter A. Buhr
    12  * Last Modified On : Sat Feb 15 11:05:50 2020
    13  * Update Count     : 737
     12 * Last Modified On : Sat Feb  1 07:16:44 2020
     13 * Update Count     : 724
    1414 */
    1515
     
    4242#include "ParseNode.h"
    4343#include "TypedefTable.h"
    44 
    45 string * build_postfix_name( string * name );
    4644
    4745char *yyfilename;
     
    332330                                /* identifier */
    333331{identifier}    { IDENTIFIER_RETURN(); }
    334 "``"{identifier} {                                                                              // CFA
    335         yytext[yyleng] = '\0'; yytext += 2;                                     // SKULLDUGGERY: remove backquotes (ok to shorten?)
     332"``"{identifier}"``" {                                                                  // CFA
     333        yytext[yyleng - 2] = '\0'; yytext += 2;                         // SKULLDUGGERY: remove backquotes (ok to shorten?)
    336334        IDENTIFIER_RETURN();
    337335}
     
    434432"?"({op_unary_pre_post}|"()"|"[?]"|"{}") { IDENTIFIER_RETURN(); }
    435433"^?{}"                  { IDENTIFIER_RETURN(); }
    436 "?`"{identifier} {                                                                              // postfix operator
    437         yylval.tok.str = new string( &yytext[2] );                      // remove ?`
    438         yylval.tok.str = build_postfix_name( yylval.tok.str ); // add prefix
    439         RETURN_LOCN( typedefTable.isKind( *yylval.tok.str ) );
    440 }
     434"?`"{identifier} { IDENTIFIER_RETURN(); }                               // postfix operator
    441435"?"{op_binary_over}"?"  { IDENTIFIER_RETURN(); }                // binary
    442436        /*
  • src/Parser/parser.yy

    ra505021 r8c50aed  
    1010// Created On       : Sat Sep  1 20:22:55 2001
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Feb 21 14:47:29 2020
    13 // Update Count     : 4468
     12// Last Modified On : Sat Feb  1 10:04:40 2020
     13// Update Count     : 4440
    1414//
    1515
     
    166166} // rebindForall
    167167
    168 string * build_postfix_name( string * name ) {
    169         *name = string("__postfix_func_") + *name;
    170         return name;
     168NameExpr * build_postfix_name( const string * name ) {
     169        NameExpr * new_name = build_varref( new string( "?`" + *name ) );
     170        delete name;
     171        return new_name;
    171172} // build_postfix_name
    172173
     
    632633                { $$ = new ExpressionNode( build_func( $1, $3 ) ); }
    633634        | postfix_expression '`' identifier                                     // CFA, postfix call
    634                 { $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref( build_postfix_name( $3 ) ) ), $1 ) ); }
     635                { $$ = new ExpressionNode( build_func( new ExpressionNode( build_postfix_name( $3 ) ), $1 ) ); }
    635636        | constant '`' identifier                                                       // CFA, postfix call
    636                 { $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref( build_postfix_name( $3 ) ) ), $1 ) ); }
     637                { $$ = new ExpressionNode( build_func( new ExpressionNode( build_postfix_name( $3 ) ), $1 ) ); }
    637638        | string_literal '`' identifier                                         // CFA, postfix call
    638                 { $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref( build_postfix_name( $3 ) ) ), new ExpressionNode( $1 ) ) ); }
     639                { $$ = new ExpressionNode( build_func( new ExpressionNode( build_postfix_name( $3 ) ), new ExpressionNode( $1 ) ) ); }
    639640        | postfix_expression '.' identifier
    640641                { $$ = new ExpressionNode( build_fieldSel( $1, build_varref( $3 ) ) ); }
     
    15891590                // type_specifier can resolve to just TYPEDEFname (e.g., typedef int T; int f( T );). Therefore this must be
    15901591                // flattened to allow lookahead to the '(' without having to reduce identifier_or_type_name.
    1591         cfa_abstract_tuple identifier_or_type_name '(' push cfa_parameter_ellipsis_list_opt pop ')' attribute_list_opt
     1592        cfa_abstract_tuple identifier_or_type_name '(' push cfa_parameter_ellipsis_list_opt pop ')'
    15921593                // To obtain LR(1 ), this rule must be factored out from function return type (see cfa_abstract_declarator).
    1593                 { $$ = DeclarationNode::newFunction( $2, $1, $5, 0 )->addQualifiers( $8 ); }
    1594         | cfa_function_return identifier_or_type_name '(' push cfa_parameter_ellipsis_list_opt pop ')' attribute_list_opt
    1595                 { $$ = DeclarationNode::newFunction( $2, $1, $5, 0 )->addQualifiers( $8 ); }
     1594                { $$ = DeclarationNode::newFunction( $2, $1, $5, 0 ); }
     1595        | cfa_function_return identifier_or_type_name '(' push cfa_parameter_ellipsis_list_opt pop ')'
     1596                { $$ = DeclarationNode::newFunction( $2, $1, $5, 0 ); }
    15961597        ;
    15971598
  • src/ResolvExpr/Resolver.cc

    ra505021 r8c50aed  
    8484                void previsit( ThrowStmt * throwStmt );
    8585                void previsit( CatchStmt * catchStmt );
    86                 void postvisit( CatchStmt * catchStmt );
    8786                void previsit( WaitForStmt * stmt );
    8887
     
    568567
    569568        void Resolver_old::previsit( CatchStmt * catchStmt ) {
    570                 // Until we are very sure this invarent (ifs that move between passes have thenPart)
    571                 // holds, check it. This allows a check for when to decode the mangling.
    572                 if ( IfStmt * ifStmt = dynamic_cast<IfStmt *>( catchStmt->body ) ) {
    573                         assert( ifStmt->thenPart );
    574                 }
    575                 // Encode the catchStmt so the condition can see the declaration.
    576569                if ( catchStmt->cond ) {
    577                         IfStmt * ifStmt = new IfStmt( catchStmt->cond, nullptr, catchStmt->body );
    578                         catchStmt->cond = nullptr;
    579                         catchStmt->body = ifStmt;
    580                 }
    581         }
    582 
    583         void Resolver_old::postvisit( CatchStmt * catchStmt ) {
    584                 // Decode the catchStmt so everything is stored properly.
    585                 IfStmt * ifStmt = dynamic_cast<IfStmt *>( catchStmt->body );
    586                 if ( nullptr != ifStmt && nullptr == ifStmt->thenPart ) {
    587                         assert( ifStmt->condition );
    588                         assert( ifStmt->elsePart );
    589                         catchStmt->cond = ifStmt->condition;
    590                         catchStmt->body = ifStmt->elsePart;
    591                         ifStmt->condition = nullptr;
    592                         ifStmt->elsePart = nullptr;
    593                         delete ifStmt;
     570                        findSingleExpression( catchStmt->cond, new BasicType( noQualifiers, BasicType::Bool ), indexer );
    594571                }
    595572        }
     
    14891466
    14901467        const ast::CatchStmt * Resolver_new::previsit( const ast::CatchStmt * catchStmt ) {
    1491                 // TODO: This will need a fix for the decl/cond scoping problem.
    14921468                if ( catchStmt->cond ) {
    14931469                        ast::ptr< ast::Type > boolType = new ast::BasicType{ ast::BasicType::Bool };
  • src/SymTab/Demangle.cc

    ra505021 r8c50aed  
    1010// Created On       : Thu Jul 19 12:52:41 2018
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Feb 11 15:09:18 2020
    13 // Update Count     : 10
     12// Last Modified On : Fri Dec 13 14:54:15 2019
     13// Update Count     : 4
    1414//
    1515
     
    1919#include "CodeGen/GenType.h"
    2020#include "Common/PassVisitor.h"
    21 #include "Common/utility.h"                                                             // isPrefix
    2221#include "Mangler.h"
    2322#include "SynTree/Type.h"
     
    417416
    418417                        bool StringView::isPrefix(const std::string & pref) {
    419                                 // if ( pref.size() > str.size()-idx ) return false;
    420                                 // auto its = std::mismatch( pref.begin(), pref.end(), std::next(str.begin(), idx) );
    421                                 // if (its.first == pref.end()) {
    422                                 //      idx += pref.size();
    423                                 //      return true;
    424                                 // }
    425 
    426                                 // This update is untested because there are no tests for this code.
    427                                 if ( ::isPrefix( str, pref, idx ) ) {
     418                                if ( pref.size() > str.size()-idx ) return false;
     419                                auto its = std::mismatch( pref.begin(), pref.end(), std::next(str.begin(), idx) );
     420                                if (its.first == pref.end()) {
    428421                                        idx += pref.size();
    429422                                        return true;
     
    436429                                PRINT( std::cerr << "====== " << str.size() << " " << str << std::endl; )
    437430                                if (str.size() < 2+Encoding::manglePrefix.size()) return false; // +2 for at least _1 suffix
    438                                 if ( ! isPrefix(Encoding::manglePrefix) || ! isdigit(str.back() ) ) return false;
     431                                if (! isPrefix(Encoding::manglePrefix) || ! isdigit(str.back())) return false;
    439432
    440433                                // get name
  • src/SymTab/Mangler.cc

    ra505021 r8c50aed  
    1010// Created On       : Sun May 17 21:40:29 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Feb 15 13:55:12 2020
    13 // Update Count     : 33
     12// Last Modified On : Fri Dec 13 23:43:49 2019
     13// Update Count     : 28
    1414//
    1515#include "Mangler.h"
     
    128128                                } // if
    129129                                mangleName << Encoding::manglePrefix;
    130                                 const CodeGen::OperatorInfo * opInfo = CodeGen::operatorLookup( declaration->get_name() );
    131                                 if ( opInfo ) {
    132                                         mangleName << opInfo->outputName.size() << opInfo->outputName;
     130                                CodeGen::OperatorInfo opInfo;
     131                                if ( operatorLookup( declaration->get_name(), opInfo ) ) {
     132                                        mangleName << opInfo.outputName.size() << opInfo.outputName;
    133133                                } else {
    134134                                        mangleName << declaration->name.size() << declaration->name;
     
    471471                        } // if
    472472                        mangleName << Encoding::manglePrefix;
    473                         const CodeGen::OperatorInfo * opInfo = CodeGen::operatorLookup( decl->name );
    474                         if ( opInfo ) {
    475                                 mangleName << opInfo->outputName.size() << opInfo->outputName;
     473                        CodeGen::OperatorInfo opInfo;
     474                        if ( operatorLookup( decl->name, opInfo ) ) {
     475                                mangleName << opInfo.outputName.size() << opInfo.outputName;
    476476                        } else {
    477477                                mangleName << decl->name.size() << decl->name;
  • src/SymTab/Validate.cc

    ra505021 r8c50aed  
    311311                        Stats::Heap::newPass("validate-A");
    312312                        Stats::Time::BlockGuard guard("validate-A");
    313                         VerifyCtorDtorAssign::verify( translationUnit );  // must happen before autogen, because autogen examines existing ctor/dtors
    314313                        acceptAll( translationUnit, hoistDecls );
    315314                        ReplaceTypedef::replaceTypedef( translationUnit );
     
    337336                        Stats::Time::BlockGuard guard("validate-C");
    338337                        acceptAll( translationUnit, genericParams );  // check as early as possible - can't happen before LinkReferenceToTypes_old
     338                        VerifyCtorDtorAssign::verify( translationUnit );  // must happen before autogen, because autogen examines existing ctor/dtors
    339339                        ReturnChecker::checkFunctionReturns( translationUnit );
    340340                        InitTweak::fixReturnStatements( translationUnit ); // must happen before autogen
     
    11821182                if ( CodeGen::isCtorDtorAssign( funcDecl->get_name() ) ) { // TODO: also check /=, etc.
    11831183                        if ( params.size() == 0 ) {
    1184                                 SemanticError( funcDecl->location, "Constructors, destructors, and assignment functions require at least one parameter." );
     1184                                SemanticError( funcDecl, "Constructors, destructors, and assignment functions require at least one parameter " );
    11851185                        }
    11861186                        ReferenceType * refType = dynamic_cast< ReferenceType * >( params.front()->get_type() );
    11871187                        if ( ! refType ) {
    1188                                 SemanticError( funcDecl->location, "First parameter of a constructor, destructor, or assignment function must be a reference." );
     1188                                SemanticError( funcDecl, "First parameter of a constructor, destructor, or assignment function must be a reference " );
    11891189                        }
    11901190                        if ( CodeGen::isCtorDtor( funcDecl->get_name() ) && returnVals.size() != 0 ) {
    1191                                 if(!returnVals.front()->get_type()->isVoid()) {
    1192                                         SemanticError( funcDecl->location, "Constructors and destructors cannot have explicit return values." );
    1193                                 }
     1191                                SemanticError( funcDecl, "Constructors and destructors cannot have explicit return values " );
    11941192                        }
    11951193                }
  • src/SynTree/Attribute.h

    ra505021 r8c50aed  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Feb 13 21:34:08 2020
    13 // Update Count     : 40
     12// Last Modified On : Sat Jul 22 09:54:14 2017
     13// Update Count     : 39
    1414//
    1515
     
    3838        virtual ~Attribute();
    3939
    40         const std::string & get_name() const { return name; }
     40        std::string get_name() const { return name; }
    4141        void set_name( const std::string & newValue ) { name = newValue; }
    4242        std::list< Expression * > & get_parameters() { return parameters; }
  • src/cfa.make

    ra505021 r8c50aed  
    3232am__v_GOC_1 =
    3333
    34 AM_V_PY = $(am__v_PY_@AM_V@)
    35 am__v_PY_ = $(am__v_PY_@AM_DEFAULT_V@)
    36 am__v_PY_0 = @echo "  PYTHON  " $@;
    37 am__v_PY_1 =
    38 
    3934AM_V_RUST = $(am__v_RUST_@AM_V@)
    4035am__v_RUST_ = $(am__v_RUST_@AM_DEFAULT_V@)
    41 am__v_RUST_0 = @echo "  RUST    " $@;
     36am__v_RUST_0 = @echo "  RUST     " $@;
    4237am__v_RUST_1 =
    4338
    4439AM_V_NODEJS = $(am__v_NODEJS_@AM_V@)
    4540am__v_NODEJS_ = $(am__v_NODEJS_@AM_DEFAULT_V@)
    46 am__v_NODEJS_0 = @echo "  NODEJS  " $@;
     41am__v_NODEJS_0 = @echo "  NODEJS     " $@;
    4742am__v_NODEJS_1 =
    4843
  • src/main.cc

    ra505021 r8c50aed  
    1010// Created On       : Fri May 15 23:12:02 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Feb  8 08:33:50 2020
    13 // Update Count     : 633
     12// Last Modified On : Mon Dec 16 17:55:53 2019
     13// Update Count     : 627
    1414//
    1515
     
    105105
    106106static void backtrace( int start ) {                                    // skip first N stack frames
    107         enum { Frames = 50, };                                                          // maximum number of stack frames
     107        enum { Frames = 50 };
    108108        void * array[Frames];
    109         size_t size = ::backtrace( array, Frames );
     109        int size = ::backtrace( array, Frames );
    110110        char ** messages = ::backtrace_symbols( array, size ); // does not demangle names
    111111
     
    114114
    115115        // skip last 2 stack frames after main
    116         for ( unsigned int i = start; i < size - 2 && messages != nullptr; i += 1 ) {
     116        for ( int i = start; i < size - 2 && messages != nullptr; i += 1 ) {
    117117                char * mangled_name = nullptr, * offset_begin = nullptr, * offset_end = nullptr;
    118118
     
    180180} // sigSegvBusHandler
    181181
    182 static void sigFpeHandler( SIGPARMS ) {
    183         const char * msg;
    184 
    185         switch ( sfp->si_code ) {
    186           case FPE_INTDIV: case FPE_FLTDIV: msg = "divide by zero"; break;
    187           case FPE_FLTOVF: msg = "overflow"; break;
    188           case FPE_FLTUND: msg = "underflow"; break;
    189           case FPE_FLTRES: msg = "inexact result"; break;
    190           case FPE_FLTINV: msg = "invalid operation"; break;
    191           default: msg = "unknown";
    192         } // choose
    193         cerr << "Computation error " << msg << " at location " << sfp->si_addr << endl
    194                  << "Possible cause is constant-expression evaluation invalid." << endl;
    195         backtrace( 2 );                                                                         // skip first 2 stack frames
    196         abort();                                                                                        // cause core dump for debugging
    197 } // sigFpeHandler
    198 
    199182static void sigAbortHandler( SIGPARMS ) {
    200183        backtrace( 6 );                                                                         // skip first 6 stack frames
     
    210193        Signal( SIGSEGV, sigSegvBusHandler, SA_SIGINFO );
    211194        Signal( SIGBUS, sigSegvBusHandler, SA_SIGINFO );
    212         Signal( SIGFPE, sigFpeHandler, SA_SIGINFO );
    213195        Signal( SIGABRT, sigAbortHandler, SA_SIGINFO );
    214196
  • tests/.expect/alloc-ERROR.txt

    ra505021 r8c50aed  
    1 alloc.cfa:310:1 error: No reasonable alternatives for expression Applying untyped:
     1alloc.cfa:311:1 error: No reasonable alternatives for expression Applying untyped:
    22  Name: ?=?
    33...to:
     
    1919
    2020
    21 alloc.cfa:311:1 error: No reasonable alternatives for expression Applying untyped:
     21alloc.cfa:312:1 error: No reasonable alternatives for expression Applying untyped:
    2222  Name: ?=?
    2323...to:
     
    3939
    4040
    41 alloc.cfa:312:1 error: No reasonable alternatives for expression Applying untyped:
     41alloc.cfa:313:1 error: No reasonable alternatives for expression Applying untyped:
    4242  Name: ?=?
    4343...to:
     
    5050
    5151
    52 alloc.cfa:313:1 error: No reasonable alternatives for expression Applying untyped:
     52alloc.cfa:314:1 error: No reasonable alternatives for expression Applying untyped:
    5353  Name: ?=?
    5454...to:
  • tests/.expect/alloc.txt

    ra505021 r8c50aed  
    22CFA malloc 0xdeadbeef
    33CFA alloc 0xdeadbeef
     4CFA array alloc, fill 0xde
    45CFA alloc, fill dededede
    56CFA alloc, fill 3
  • tests/.expect/nested-types-ERR1.txt

    ra505021 r8c50aed  
    1 nested-types.cfa:83:1 error: Use of undefined type T
     1nested-types.cfa:70:1 error: Use of undefined type T
  • tests/.expect/nested-types-ERR2.txt

    ra505021 r8c50aed  
    1 nested-types.cfa:86:1 error: Use of undefined global type Z
    2 nested-types.cfa:87:1 error: Qualified type requires an aggregate on the left, but has: signed int
    3 nested-types.cfa:88:1 error: Undefined type in qualified type: Qualified Type:
     1nested-types.cfa:73:1 error: Use of undefined global type Z
     2nested-types.cfa:74:1 error: Qualified type requires an aggregate on the left, but has: signed int
     3nested-types.cfa:75:1 error: Undefined type in qualified type: Qualified Type:
    44  instance of struct S with body 1
    55  instance of type Z (not function type)
  • tests/.expect/rational.txt

    ra505021 r8c50aed  
    11constructor
    2 3/1 4/1 0/1 0/1 1/1
     23/1 4/1 0/1
    331/2 5/7
    442/3 -3/2
  • tests/Makefile.in

    ra505021 r8c50aed  
    374374am__v_GOC_0 = @echo "  GOC     " $@;
    375375am__v_GOC_1 =
    376 AM_V_PY = $(am__v_PY_@AM_V@)
    377 am__v_PY_ = $(am__v_PY_@AM_DEFAULT_V@)
    378 am__v_PY_0 = @echo "  PYTHON  " $@;
    379 am__v_PY_1 =
    380376AM_V_RUST = $(am__v_RUST_@AM_V@)
    381377am__v_RUST_ = $(am__v_RUST_@AM_DEFAULT_V@)
    382 am__v_RUST_0 = @echo "  RUST    " $@;
     378am__v_RUST_0 = @echo "  RUST     " $@;
    383379am__v_RUST_1 =
    384380AM_V_NODEJS = $(am__v_NODEJS_@AM_V@)
    385381am__v_NODEJS_ = $(am__v_NODEJS_@AM_DEFAULT_V@)
    386 am__v_NODEJS_0 = @echo "  NODEJS  " $@;
     382am__v_NODEJS_0 = @echo "  NODEJS     " $@;
    387383am__v_NODEJS_1 =
    388384AM_V_JAVAC = $(am__v_JAVAC_@AM_V@)
  • tests/alloc.cfa

    ra505021 r8c50aed  
    1010// Created On       : Wed Feb  3 07:56:22 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Feb 16 09:21:13 2020
    13 // Update Count     : 405
     12// Last Modified On : Fri Nov 22 15:34:19 2019
     13// Update Count     : 404
    1414//
    1515
     
    4848
    4949        p = alloc_set( fill );                                                          // CFA alloc, fill
     50        printf( "CFA array alloc, fill %#hhx\n", fill );
    5051        printf( "CFA alloc, fill %08x\n", *p );
    5152        free( p );
  • tests/concurrent/examples/quickSort.cfa

    ra505021 r8c50aed  
    1111// Created On       : Wed Dec  6 12:15:52 2017
    1212// Last Modified By : Peter A. Buhr
    13 // Last Modified On : Wed Feb 12 18:24:47 2020
    14 // Update Count     : 177
     13// Last Modified On : Thu Oct 10 13:58:18 2019
     14// Update Count     : 176
    1515//
    1616
     
    2727
    2828void ?{}( Quicksort & qs, int values[], int size, int depth ) {
    29         qs.[values, low, high, depth] = [values, 0, size, depth];
     29        qs.values = values;  qs.low = 0;  qs.high = size;  qs.depth = depth;
    3030} // Quicksort
    3131
     
    167167                        values[counter] = size - counter;                       // descending values
    168168                } // for
    169                 for ( i; 200 ) {                                                                // random shuffle a few values
     169                for ( int i = 0; i < 200; i +=1 ) {                             // random shuffle a few values
    170170                        swap( values[rand() % size], values[rand() % size] );
    171171                } // for
  • tests/exceptions/except-0.cfa

    ra505021 r8c50aed  
    1919};
    2020
    21 void ?{}(signal_exit & this, const char * area) {
    22         this.area = area;
    23 }
    24 
    25 void ^?{}(signal_exit & this) {
    26         printf("Exiting: %s\n", this.area);
     21void ?{}(signal_exit * this, const char * area) {
     22        this->area = area;
     23}
     24
     25void ^?{}(signal_exit * this) {
     26        printf("Exiting: %s\n", this->area);
    2727//      sout | "Exiting:" | this->area;
    2828}
     
    242242
    243243        // Uncaught termination test.
    244         /* Removed due to non-deterministic output.
    245244        printf("Throw uncaught.\n");
    246245        yang z;
    247246        terminate(&z);
    248         */
    249 }
     247}
  • tests/exceptions/except-2.cfa

    ra505021 r8c50aed  
    1212        struct TABLE(BASE_EXCEPT) const * parent;
    1313        size_t size;
    14         void (*copy)(num_error &this, num_error & other);
    15         void (*free)(num_error &this);
     14        void (*copy)(num_error *this, num_error * other);
     15        void (*free)(num_error *this);
    1616        const char * (*msg)(num_error *this);
    1717        int (*code)(num_error *this);
     
    2828        if ( ! this->msg ) {
    2929                static const char * base = "Num Error with code: X";
    30                 this->msg = (char *)malloc(22);
     30                this->msg = malloc(22);
    3131                for (int i = 0 ; (this->msg[i] = base[i]) ; ++i);
    3232        }
     
    3434        return this->msg;
    3535}
    36 void ?{}(num_error & this, int num) {
    37         this.virtual_table = &INSTANCE(num_error);
    38         this.msg = 0;
    39         this.num = num;
     36void ?{}(num_error * this, int num) {
     37        this->virtual_table = &INSTANCE(num_error);
     38        this->msg = 0;
     39        this->num = num;
    4040}
    41 void ?{}(num_error & this, num_error & other) {
    42         this.virtual_table = other.virtual_table;
    43         this.msg = 0;
    44         this.num = other.num;
     41void ?{}(num_error * this, num_error * other) {
     42        this->virtual_table = other->virtual_table;
     43        this->msg = 0;
     44        this->num = other->num;
    4545}
    46 void ^?{}(num_error & this) {
    47         if( this.msg ) free( this.msg );
     46void ^?{}(num_error * this) {
     47        if( this->msg ) free( this->msg );
    4848}
    4949int num_error_code( num_error * this ) {
  • tests/labelledExit.cfa

    ra505021 r8c50aed  
    1010// Created On       : Wed Aug 10 07:29:39 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Feb  5 16:49:48 2020
    13 // Update Count     : 9
     12// Last Modified On : Fri Oct 25 17:41:51 2019
     13// Update Count     : 7
    1414//
    1515
     
    162162
    163163        // computed goto
    164         {
    165                 void *array[] = { &&foo, &&bar, &&hack };
    166           foo: bar: hack:
    167                 &&foo;
    168                 &&bar;
    169                 goto *array[i];
    170         }
     164        // {
     165        //      void *array[] = { &&foo, &&bar, &&hack };
     166        //   foo: bar: hack:
     167        //      &&foo;
     168        //      &&bar;
     169        //      goto *array[i];
     170        // }
    171171
    172172  Q: if ( i > 5 ) {
  • tests/nested-types.cfa

    ra505021 r8c50aed  
    1010// Created On       : Mon Jul 9 10:20:03 2018
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Feb 12 18:21:15 2020
    13 // Update Count     : 3
     12// Last Modified On : Tue Nov  6 17:59:40 2018
     13// Update Count     : 2
    1414//
    1515
     
    5050//   double d;
    5151// };
    52 
    53 // struct S {
    54 //     enum C { R, G, B };
    55 //     int i;
    56 //     struct T {
    57 //      int i;
    58 //     };
    59 //     T t;
    60 // };
    61 
    62 // S s;
    63 // S.C c;
    64 // S.T t;
    6552
    6653int main() {
  • tests/pybin/tools.py

    ra505021 r8c50aed  
    175175
    176176def which(program):
    177         fpath, fname = os.path.split(program)
    178         if fpath:
    179                 if is_exe(program):
    180                         return program
    181         else:
    182                 for path in os.environ["PATH"].split(os.pathsep):
    183                         exe_file = os.path.join(path, program)
    184                         if is_exe(exe_file):
    185                                 return exe_file
    186         return None
     177    fpath, fname = os.path.split(program)
     178    if fpath:
     179        if is_exe(program):
     180            return program
     181    else:
     182        for path in os.environ["PATH"].split(os.pathsep):
     183            exe_file = os.path.join(path, program)
     184            if is_exe(exe_file):
     185                return exe_file
     186
     187    return None
    187188
    188189@contextlib.contextmanager
     
    364365
    365366class Timed:
    366         def __enter__(self):
    367                 self.start = time.time()
    368                 return self
    369 
    370         def __exit__(self, *args):
    371                 self.end = time.time()
    372                 self.duration = self.end - self.start
     367    def __enter__(self):
     368        self.start = time.time()
     369        return self
     370
     371    def __exit__(self, *args):
     372        self.end = time.time()
     373        self.duration = self.end - self.start
    373374
    374375def timed(src, timeout):
    375376        expire = time.time() + timeout
    376377        i = iter(src)
    377         with contextlib.suppress(StopIteration):
    378                 while True:
    379                         yield i.next(max(expire - time.time(), 0))
     378        while True:
     379                yield i.next(max(expire - time.time(), 0))
  • tests/quotedKeyword.cfa

    ra505021 r8c50aed  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Feb  7 19:07:07 2020
    13 // Update Count     : 25
     12// Last Modified On : Sat Feb  1 00:02:22 2020
     13// Update Count     : 24
    1414//
    1515
     
    1717
    1818struct {
    19         int ``otype;
    20         int ``struct;
     19        int ``otype``;
     20        int ``struct``;
    2121} st = { 10, 10 };
    2222
    23 typedef int ``forall;
    24 ``forall xxx = 10;
     23typedef int ``forall``;
     24``forall`` xxx = 10;
    2525
    26 int ``_Alignas, ``_Alignof, ``__alignof, ``__alignof__, ``asm, ``__asm, ``__asm__, ``_At, ``_Atomic, ``__attribute,
    27         ``__attribute__, ``auto, ``_Bool, ``break, ``case, ``catch, ``catchResume, ``char, ``choose, ``_Complex, ``__complex,
    28         ``__complex__, ``const, ``__const, ``__const__, ``continue, ``default, ``disable, ``do, ``double, ``dtype, ``else,
    29         ``enable, ``enum, ``__extension__, ``extern, ``fallthru, ``finally, ``float, ``__float128, ``for, ``forall, ``fortran,
    30         ``ftype, ``_Generic, ``goto, ``if, ``_Imaginary, ``__imag, ``__imag__, ``inline, ``__inline, ``__inline__, ``int,
    31         ``__int128, ``__label__, ``long, ``lvalue, ``_Noreturn, ``__builtin_offsetof, ``otype, ``register, ``restrict,
    32         ``__restrict, ``__restrict__, ``return, ``short, ``signed, ``__signed, ``__signed__, ``sizeof, ``static,
    33         ``_Static_assert, ``struct, ``switch, ``_Thread_local, ``throw, ``throwResume, ``trait, ``try, ``typedef,
    34         ``typeof, ``__typeof, ``__typeof__, ``union, ``unsigned, ``__builtin_va_list, ``void, ``volatile, ``__volatile,
    35         ``__volatile__, ``while;
     26int ``_Alignas``, ``_Alignof``, ``__alignof``, ``__alignof__``, ``asm``, ``__asm``, ``__asm__``, ``_At``, ``_Atomic``, ``__attribute``,
     27        ``__attribute__``, ``auto``, ``_Bool``, ``break``, ``case``, ``catch``, ``catchResume``, ``char``, ``choose``, ``_Complex``, ``__complex``,
     28        ``__complex__``, ``const``, ``__const``, ``__const__``, ``continue``, ``default``, ``disable``, ``do``, ``double``, ``dtype``, ``else``,
     29        ``enable``, ``enum``, ``__extension__``, ``extern``, ``fallthru``, ``finally``, ``float``, ``__float128``, ``for``, ``forall``, ``fortran``,
     30        ``ftype``, ``_Generic``, ``goto``, ``if``, ``_Imaginary``, ``__imag``, ``__imag__``, ``inline``, ``__inline``, ``__inline__``, ``int``,
     31        ``__int128``, ``__label__``, ``long``, ``lvalue``, ``_Noreturn``, ``__builtin_offsetof``, ``otype``, ``register``, ``restrict``,
     32        ``__restrict``, ``__restrict__``, ``return``, ``short``, ``signed``, ``__signed``, ``__signed__``, ``sizeof``, ``static``,
     33        ``_Static_assert``, ``struct``, ``switch``, ``_Thread_local``, ``throw``, ``throwResume``, ``trait``, ``try``, ``typedef``,
     34        ``typeof``, ``__typeof``, ``__typeof__``, ``union``, ``unsigned``, ``__builtin_va_list``, ``void``, ``volatile``, ``__volatile``,
     35        ``__volatile__``, ``while``;
    3636
    3737int main() {
    38         int ``if = 0;
    39         ``catch = 1;
    40         st.``otype = 2;
    41         st.``struct = 3;
    42         ``throw = 4;
    43         sout | ``catch + st.``otype + st.``struct + ``throw;
     38        int ``if`` = 0;
     39        ``catch`` = 1;
     40        st.``otype`` = 2;
     41        st.``struct`` = 3;
     42        ``throw`` = 4;
     43        sout | ``catch`` + st.``otype`` + st.``struct`` + ``throw``;
    4444}
    4545
  • tests/rational.cfa

    ra505021 r8c50aed  
    1010// Created On       : Mon Mar 28 08:43:12 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Feb  8 18:46:23 2020
    13 // Update Count     : 86
     12// Last Modified On : Wed Mar 27 07:37:17 2019
     13// Update Count     : 80
    1414//
    1515
     
    1919#include <fstream.hfa>
    2020
    21 typedef Rational(int) RatInt;
    22 double convert( int i ) { return (double)i; }                   // used by narrow/widen
     21double convert( int i ) { return (double)i; }
    2322int convert( double d ) { return (int)d; }
    2423
    2524int main() {
    2625        sout | "constructor";
    27         RatInt a = { 3 }, b = { 4 }, c, d = 0, e = 1;
    28         sout | a | b | c | d | e;
     26        Rational(int) a = { 3 }, b = { 4 }, c;
     27        sout | a | b | c;
    2928
    30         a = (RatInt){ 4, 8 };
    31         b = (RatInt){ 5, 7 };
     29        a = (Rational(int)){ 4, 8 };
     30        b = (Rational(int)){ 5, 7 };
    3231        sout | a | b;
    33         a = (RatInt){ -2, -3 };
    34         b = (RatInt){ 3, -2 };
     32        a = (Rational(int)){ -2, -3 };
     33        b = (Rational(int)){ 3, -2 };
    3534        sout | a | b;
    36         a = (RatInt){ -2, 3 };
    37         b = (RatInt){ 3, 2 };
     35        a = (Rational(int)){ -2, 3 };
     36        b = (Rational(int)){ 3, 2 };
    3837        sout | a | b;
    3938
    4039        sout | "logical";
    41         a = (RatInt){ -2 };
    42         b = (RatInt){ -3, 2 };
     40        a = (Rational(int)){ -2 };
     41        b = (Rational(int)){ -3, 2 };
    4342        sout | a | b;
    4443//      sout | a == 1; // FIX ME
     
    5958
    6059        sout | "conversion";
    61         a = (RatInt){ 3, 4 };
     60        a = (Rational(int)){ 3, 4 };
    6261        sout | widen( a );
    63         a = (RatInt){ 1, 7 };
     62        a = (Rational(int)){ 1, 7 };
    6463        sout | widen( a );
    65         a = (RatInt){ 355, 113 };
     64        a = (Rational(int)){ 355, 113 };
    6665        sout | widen( a );
    6766        sout | narrow( 0.75, 4 );
     
    7574
    7675        sout | "more tests";
    77         RatInt x = { 1, 2 }, y = { 2 };
     76        Rational(int) x = { 1, 2 }, y = { 2 };
    7877        sout | x - y;
    7978        sout | x > y;
     
    8180        sout | y | denominator( y, -2 ) | y;
    8281
    83         RatInt z = { 0, 5 };
     82        Rational(int) z = { 0, 5 };
    8483        sout | z;
    8584
    8685        sout | x | numerator( x, 0 ) | x;
    8786
    88         x = (RatInt){ 1, MAX } + (RatInt){ 1, MAX };
     87        x = (Rational(int)){ 1, MAX } + (Rational(int)){ 1, MAX };
    8988        sout | x;
    90         x = (RatInt){ 3, MAX } + (RatInt){ 2, MAX };
     89        x = (Rational(int)){ 3, MAX } + (Rational(int)){ 2, MAX };
    9190        sout | x;
    9291
  • tests/test.py

    ra505021 r8c50aed  
    152152        # run everything in a temp directory to make sure core file are handled properly
    153153        with tempdir():
    154                 # if the make command succeeds continue otherwise skip to diff
     154                # if the make command succeds continue otherwise skip to diff
    155155                if success(make_ret):
    156156                        with Timed() as run_dur:
  • tests/userLiterals.cfa

    ra505021 r8c50aed  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // userLiterals.cfa --
     7// user_literals.cfa --
    88//
    99// Author           : Peter A. Buhr
    1010// Created On       : Wed Sep  6 21:40:50 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Feb 19 07:48:45 2020
    13 // Update Count     : 74
     12// Last Modified On : Tue Dec  4 22:03:10 2018
     13// Update Count     : 56
    1414//
    1515
     
    2424int ?`__thingy_( int x ) { sout | "_thingy_" | x; return x; }
    2525
    26 int ?`s( const char * s ) { sout | "s" | s; return 0; }
    27 int ?`m( const char16_t * m ) { sout | "m" | m; return 0;}
    28 int ?`h( const char32_t * h ) { sout | "h" | h; return 0; }
     26int ?`s( const char * s ) { sout | "secs" | s; return 0; }
     27int ?`m( const char16_t * m ) { sout | "mins" | m; return 0;}
     28int ?`h( const char32_t * h ) { sout | "hours" | h; return 0; }
    2929int ?`_A_( const wchar_t * str ) { sout | "_A_" | str; return 0; }
    3030int ?`__thingy_( const char * str ) { sout | "_thingy_" | str; return 0; }
     
    3737        return (Weight){ l.stones + r.stones };
    3838}
    39 ofstream & ?|?( ofstream & os, Weight w ) { return os | wd(1,1, w.stones); }
    40 void ?|?( ofstream & os, Weight w ) { (ofstream)(os | w); ends( os ); }
     39ofstream & ?|?( ofstream & os, Weight w ) { return os | w.stones; }
    4140
    4241Weight ?`st( double w ) { return (Weight){ w }; }               // backquote for user literals
     
    6160        sout | w;
    6261
    63         0`s;
     62//      0`secs;
    6463        1`s;
    6564        23`s;
     
    8382
    8483        "abc"`s;
    85         // FIX ME: requires char16_t, char32_t, and wchar_t be unique types
    86         // u"abc"`m;
    87         // U_"abc"`h;
    88         // L"abc"`_A_;
     84//      u"abc"`m;
     85//      U_"abc"`h;
     86//      L"abc"`_A_;
    8987        u8_"abc"`__thingy_;
    9088} // main
     
    9290// Local Variables: //
    9391// tab-width: 4 //
    94 // compile-command: "cfa userLiterals.cfa" //
     92// compile-command: "cfa user_literals.cfa" //
    9593// End: //
Note: See TracChangeset for help on using the changeset viewer.