Changeset fc12f05 for libcfa


Ignore:
Timestamp:
Nov 13, 2023, 3:43:43 AM (2 years ago)
Author:
JiadaL <j82liang@…>
Branches:
master
Children:
25f2798
Parents:
0030b508 (diff), 2174191 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Location:
libcfa
Files:
14 edited
3 moved

Legend:

Unmodified
Added
Removed
  • libcfa/prelude/Makefile.am

    r0030b508 rfc12f05  
    1111## Created On       : Sun May 31 08:54:01 2015
    1212## Last Modified By : Peter A. Buhr
    13 ## Last Modified On : Thu Jan 13 17:06:27 2022
    14 ## Update Count     : 215
     13## Last Modified On : Wed Nov  1 21:09:25 2023
     14## Update Count     : 221
    1515###############################################################################
    1616
     
    2121# put into lib for now
    2222cfalibdir = ${CFA_LIBDIR}
    23 cfalib_DATA = gcc-builtins.cf builtins.cf extras.cf prelude.cfa bootloader.c defines.hfa
     23cfalib_DATA = gcc-builtins.cfa builtins.cfa extras.cfa prelude.cfa bootloader.c defines.hfa
    2424
    25 EXTRA_DIST = bootloader.cf builtins.c builtins.def extras.c extras.regx extras.regx2 prelude-gen.cc prototypes.awk prototypes.c prototypes.sed sync-builtins.cf
     25EXTRA_DIST = bootloader.cfa builtins.c builtins.def extras.c extras.regx extras.regx2 prelude-gen.cc prototypes.awk prototypes.c prototypes.sed sync-builtins.cfa
    2626
    2727CC = @LOCAL_CFACC@
     
    3636
    3737# create extra forward types/declarations to reduce inclusion of library files
    38 extras.cf : ${srcdir}/extras.regx ${srcdir}/extras.c
     38extras.cfa : ${srcdir}/extras.regx ${srcdir}/extras.c
    3939        @echo '# 2 "${@}"  // needed for error messages from this file' > ${@}
    4040        ${AM_V_GEN}gcc ${AM_CFLAGS} -E ${srcdir}/extras.c | grep -f ${srcdir}/extras.regx >> ${@}
     
    4242
    4343# create forward declarations for gcc builtins
    44 gcc-builtins.cf : gcc-builtins.c ${srcdir}/prototypes.sed
     44gcc-builtins.cfa : gcc-builtins.c ${srcdir}/prototypes.sed
    4545        @echo '# 2 "${@}"  // needed for error messages from this file' > ${@}
    4646        ${AM_V_GEN}gcc -I${srcdir} -E -P $< | sed -r -f ${srcdir}/prototypes.sed >> ${@}
    4747
    48 gcc-builtins.c : ${srcdir}/builtins.def ${srcdir}/prototypes.awk ${srcdir}/sync-builtins.cf ${srcdir}/prototypes.c
     48gcc-builtins.c : ${srcdir}/builtins.def ${srcdir}/prototypes.awk ${srcdir}/sync-builtins.cfa ${srcdir}/prototypes.c
    4949        ${AM_V_GEN}gcc -I${srcdir} -E ${srcdir}/prototypes.c | awk -f ${srcdir}/prototypes.awk > ${@}
    5050
     
    5959
    6060# create forward declarations for cfa builtins
    61 builtins.cf : builtins.c @LOCAL_CFACC@
     61builtins.cfa : builtins.c @LOCAL_CFACC@
    6262        ${AM_V_GEN}gcc ${AM_CFLAGS} -E ${<} -o ${@} -MD -MP -MF $(DEPDIR)/builtins.Po -D__cforall
    63         ${AM_V_at}sed -i 's/builtins.o/builtins.cf/g' $(DEPDIR)/builtins.Po
     63        ${AM_V_at}sed -i 's/builtins.o/builtins.cfa/g' $(DEPDIR)/builtins.Po
    6464
    6565include $(DEPDIR)/builtins.Po
    6666
    67 bootloader.c : ${srcdir}/bootloader.cf prelude.cfa extras.cf gcc-builtins.cf builtins.cf @CFACPP@
    68         ${AM_V_GEN}@CFACPP@ --prelude-dir=${builddir} -tpm ${srcdir}/bootloader.cf ${@}  # use src/cfa-cpp as not in lib until after install
     67bootloader.c : ${srcdir}/bootloader.cfa prelude.cfa extras.cfa gcc-builtins.cfa builtins.cfa @CFACPP@
     68        ${AM_V_GEN}@CFACPP@ --prelude-dir=${builddir} -tpm ${srcdir}/bootloader.cfa ${@}  # use src/cfa-cpp as not in lib until after install
    6969
    7070maintainer-clean-local :
    7171        rm -rf $(DEPDIR)
    7272
    73 MOSTLYCLEANFILES = bootloader.c builtins.cf extras.cf gcc-builtins.c gcc-builtins.cf prelude.cfa
     73MOSTLYCLEANFILES = bootloader.c builtins.cfa extras.cfa gcc-builtins.c gcc-builtins.cfa prelude.cfa
    7474DISTCLEANFILES = $(DEPDIR)/builtins.Po
    7575MAINTAINERCLEANFILES = ${addprefix ${libdir}/,${cfalib_DATA}} ${addprefix ${libdir}/,${lib_LIBRARIES}}
    7676
    7777if ENABLE_DISTCC
    78 distribution: @LOCAL_CFACC@ @LOCAL_CC1@ @CFACPP@ defines.hfa gcc-builtins.cf builtins.cf extras.cf prelude.cfa bootloader.c $(srcdir)/../../tools/build/push2dist.sh
     78distribution: @LOCAL_CFACC@ @LOCAL_CC1@ @CFACPP@ defines.hfa gcc-builtins.cfa builtins.cfa extras.cfa prelude.cfa bootloader.c $(srcdir)/../../tools/build/push2dist.sh
    7979        ${AM_V_GEN}$(srcdir)/../../tools/build/push2dist.sh @CFADIR_HASH@ @DIST_BWLIMIT@
    8080        @echo "Dummy file to track distribution to remote hosts" > ${@}
  • libcfa/prelude/prototypes.awk

    r0030b508 rfc12f05  
    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 : Wed Nov  1 20:44:04 2023
     13# Update Count     : 37
    1414#
    1515
     
    150150        # extras
    151151        printf( "\n#include \"builtins.def\"\n\n" );
    152         printf( "\n#include \"sync-builtins.cf\"\n\n" );
     152        printf( "\n#include \"sync-builtins.cfa\"\n\n" );
    153153        printf( "extern const char *__PRETTY_FUNCTION__;\n" );
    154154        printf( "float _Complex __builtin_complex( float, float );\n" );
  • libcfa/src/Makefile.am

    r0030b508 rfc12f05  
    1111## Created On       : Sun May 31 08:54:01 2015
    1212## Last Modified By : Peter A. Buhr
    13 ## Last Modified On : Mon Sep 18 17:06:56 2023
    14 ## Update Count     : 264
     13## Last Modified On : Wed Nov  1 19:03:42 2023
     14## Update Count     : 266
    1515###############################################################################
    1616
     
    195195if ENABLE_DISTCC
    196196
    197 ../prelude/distribution: @LOCAL_CFACC@ @LOCAL_CC1@ @CFACPP@ ../prelude/defines.hfa ../prelude/gcc-builtins.cf ../prelude/builtins.cf ../prelude/extras.cf ../prelude/prelude.cfa ../prelude/bootloader.c $(srcdir)/../../tools/build/push2dist.sh
     197../prelude/distribution: @LOCAL_CFACC@ @LOCAL_CC1@ @CFACPP@ ../prelude/defines.hfa ../prelude/gcc-builtins.cfa ../prelude/builtins.cfa ../prelude/extras.cfa ../prelude/prelude.cfa ../prelude/bootloader.c $(srcdir)/../../tools/build/push2dist.sh
    198198        @+make -C ../prelude distribution
    199199
     
    202202endif ENABLE_DISTCC
    203203
    204 prelude.o : prelude.cfa extras.cf gcc-builtins.cf builtins.cf @LOCAL_CFACC@ @CFACPP@
     204prelude.o : prelude.cfa extras.cfa gcc-builtins.cfa builtins.cfa @LOCAL_CFACC@ @CFACPP@
    205205        ${AM_V_GEN}$(CFACOMPILE) -quiet -XCFA,-l ${<} -c -fvisibility=default -o ${@}
    206206
    207 prelude.lo: prelude.cfa extras.cf gcc-builtins.cf builtins.cf @LOCAL_CFACC@ @CFACPP@
     207prelude.lo: prelude.cfa extras.cfa gcc-builtins.cfa builtins.cfa @LOCAL_CFACC@ @CFACPP@
    208208        ${AM_V_GEN}$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile \
    209209        $(CFACOMPILE) -quiet -XCFA,-l ${<} -c -fvisibility=default -o ${@}
  • libcfa/src/collections/string.cfa

    r0030b508 rfc12f05  
    1010// Created On       : Fri Sep 03 11:00:00 2021
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Sep  2 12:05:57 2023
    13 // Update Count     : 206
     12// Last Modified On : Wed Oct 18 21:52:09 2023
     13// Update Count     : 208
    1414//
    1515
     
    138138
    139139void ?|?( ifstream & in, _Istream_Sstr f ) {
    140     (ifstream &)(in | f); ends( in );
     140    (ifstream &)(in | f);
    141141}
    142142
  • libcfa/src/collections/string_res.cfa

    r0030b508 rfc12f05  
    1010// Created On       : Fri Sep 03 11:00:00 2021
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Aug 14 18:06:01 2023
    13 // Update Count     : 12
     12// Last Modified On : Wed Oct 18 21:54:54 2023
     13// Update Count     : 15
    1414//
    1515
     
    236236        // get bytes
    237237        try {
     238                        *(temp.Handle.ulink->EndVbyte) = '\0';   // pre-assign empty cstring
    238239            in | wdi( lenReadable, temp.Handle.ulink->EndVbyte );
    239240        } catch (cstring_length*) {
     
    247248    }
    248249
    249     s = temp;
     250        if ( temp.Handle.lnth > 0 ) s = temp;
    250251    return in;
    251252}
    252253
    253254void ?|?( ifstream & in, string_res & this ) {
    254     (ifstream &)(in | this); ends( in );
     255    (ifstream &)(in | this);
    255256}
    256257
     
    268269        cstr[wd] = '\0';                                                                        // guard null terminate string
    269270        try {
     271                cstr[0] = '\0';                                                                 // pre-assign as empty cstring
    270272                is | cf;
    271273        } catch( cstring_length * ) {
    272274                cont = true;
    273275        } finally {
    274         if ( ! cf.flags.ignore ) *(f.s) = cstr;                 // ok to initialize string
     276                if ( ! cf.flags.ignore &&                                               // ok to initialize string
     277                                cstr[0] != '\0' ) {                                             // something was read
     278                        *(f.s) = cstr;
     279                }
    275280        } // try
    276281        for ( ; cont; )  {                                                                      // overflow read ?
    277282                cont = false;
    278283                try {
     284                        cstr[0] = '\0';                                                         // pre-assign as empty cstring
    279285                        is | cf;
    280286                } catch( cstring_length * ) {
    281287                        cont = true;                                                            // continue not allowed
    282288                } finally {
    283                         if ( ! cf.flags.ignore ) *(f.s) += cstr;        // build string chunk at a time
     289                        if ( ! cf.flags.ignore &&
     290                                        cstr[0] != '\0' ) {                                     // something was read
     291                                *(f.s) += cstr;                                                 // build string chunk at a time
     292                        }
    284293                } // try
    285294        } // for
     
    288297
    289298void ?|?( ifstream & in, _Istream_Rstr f ) {
    290     (ifstream &)(in | f); ends( in );
     299    (ifstream &)(in | f);
    291300}
    292301
  • libcfa/src/concurrency/channel.hfa

    r0030b508 rfc12f05  
    130130static inline void __cons_handoff( channel(T) & chan, T & elem ) with(chan) {
    131131    memcpy( cons`first.extra, (void *)&elem, sizeof(T) ); // do waiting consumer work
    132     __atomic_thread_fence( __ATOMIC_SEQ_CST );
    133132    wake_one( cons );
    134133}
     
    137136static inline void __prods_handoff( channel(T) & chan, T & retval ) with(chan) {
    138137    memcpy( (void *)&retval, prods`first.extra, sizeof(T) );
    139     __atomic_thread_fence( __ATOMIC_SEQ_CST );
    140138    wake_one( prods );
    141139}
  • libcfa/src/concurrency/cofor.cfa

    r0030b508 rfc12f05  
    44// cofor ( uC++ COFOR )
    55
    6 thread cofor_runner {
     6thread cofor_task {
    77        ssize_t low, high;
    88        __cofor_body_t loop_body;
    99};
    1010
    11 static void ?{}( cofor_runner & this, ssize_t low, ssize_t high, __cofor_body_t loop_body ) {
     11static void ?{}( cofor_task & this, ssize_t low, ssize_t high, __cofor_body_t loop_body ) {
    1212        this.low = low;
    1313        this.high = high;
     
    1515}
    1616
    17 void main( cofor_runner & this ) with( this ) {
     17void main( cofor_task & this ) with( this ) {
    1818        for ( ssize_t i = low; i < high; i++ )
    1919                loop_body(i);
     
    2929        ssize_t i = 0;
    3030        ssize_t stride_iter = low;
    31         cofor_runner * runners[ threads ];
     31        cofor_task * runners[ threads ];
    3232        for ( i; threads ) {
    3333                runners[i] = alloc();
  • libcfa/src/concurrency/cofor.hfa

    r0030b508 rfc12f05  
    11#include <thread.hfa>
     2#include <locks.hfa>
     3#include <list.hfa>
    24
    35//////////////////////////////////////////////////////////////////////////////////////////
     
    1416                __Cofor__( low, high, __CFA_loopLambda__ ); \
    1517        }
     18
     19struct runner_node {
     20    void * value;
     21    inline dlink(runner_node);
     22};
     23P9_EMBEDDED( runner_node, dlink(runner_node) )
     24
     25thread cofor_runner {
     26        go_mutex mutex_lock;              // MX lock
     27    dlist( runner_node ) items;
     28    void (*func)(void *);
     29    volatile bool done;
     30};
     31
     32void ?{}( cofor_runner & this ) { this.done = false; }
     33
     34void main( cofor_runner & this ) with(this) {
     35    while ( !done || !items`isEmpty ) {
     36                lock( mutex_lock );
     37        runner_node * node = &try_pop_front( items );
     38                unlock( mutex_lock );
     39        func( node->value );
     40        free( node->value );
     41        free( node );
     42    }
     43}
     44
     45void start_runners( cofor_runner * thds, unsigned nprocs, void (*func)(void *) ) {
     46        for ( i; nprocs ) {
     47                thds[i].func = func;
     48        }
     49}
     50
     51void end_runners( cofor_runner * thds, unsigned nprocs ) {
     52        for ( i; nprocs ) {
     53                thds[i].done = true;
     54        }
     55}
     56
     57void send_work( cofor_runner * thds, unsigned nprocs, unsigned & curr_proc, void * value ) {
     58        runner_node * node = malloc();
     59        (*node){};
     60        node->value = value;
     61        lock( thds[curr_proc].mutex_lock );
     62        insert_last( thds[curr_proc].items, *node );
     63        unlock( thds[curr_proc].mutex_lock );
     64        curr_proc = ( curr_proc + 1 ) % nprocs;
     65}
    1666
    1767//////////////////////////////////////////////////////////////////////////////////////////
     
    4292    delete( this.runner );
    4393}
    44 
  • libcfa/src/concurrency/kernel.hfa

    r0030b508 rfc12f05  
    303303// gets the number of constructed processors on the cluster
    304304static inline unsigned get_proc_count( cluster & this ) { return this.procs.constructed; }
     305static inline unsigned get_proc_count() { return publicTLS_get( this_processor )->cltr->procs.constructed; }
    305306
    306307// set the number of internal processors
  • libcfa/src/concurrency/locks.hfa

    r0030b508 rfc12f05  
    182182static inline void lock( mcs_spin_lock & l, mcs_spin_node & n ) {
    183183    n.locked = true;
     184
     185        #if defined(__ARM_ARCH)
     186        __asm__ __volatile__ ( "DMB ISH" ::: );
     187        #endif
     188
    184189        mcs_spin_node * prev = __atomic_exchange_n(&l.queue.tail, &n, __ATOMIC_SEQ_CST);
    185190        if( prev == 0p ) return;
    186191        prev->next = &n;
     192       
     193        #if defined(__ARM_ARCH)
     194        __asm__ __volatile__ ( "DMB ISH" ::: );
     195        #endif
     196
    187197        while( __atomic_load_n(&n.locked, __ATOMIC_RELAXED) ) Pause();
     198
     199        #if defined(__ARM_ARCH)
     200        __asm__ __volatile__ ( "DMB ISH" ::: );
     201        #endif
    188202}
    189203
    190204static inline void unlock(mcs_spin_lock & l, mcs_spin_node & n) {
     205        #if defined(__ARM_ARCH)
     206        __asm__ __volatile__ ( "DMB ISH" ::: );
     207        #endif
     208
    191209        mcs_spin_node * n_ptr = &n;
    192210        if (__atomic_compare_exchange_n(&l.queue.tail, &n_ptr, 0p, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) return;
    193211        while (__atomic_load_n(&n.next, __ATOMIC_RELAXED) == 0p) Pause();
     212
     213        #if defined(__ARM_ARCH)
     214        __asm__ __volatile__ ( "DMB ISH" ::: );
     215        #endif
     216
    194217        n.next->locked = false;
    195218}
  • libcfa/src/fstream.cfa

    r0030b508 rfc12f05  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Aug 18 10:41:17 2023
    13 // Update Count     : 541
     12// Last Modified On : Wed Oct 18 22:05:54 2023
     13// Update Count     : 549
    1414//
    1515
     
    230230void nlOff( ifstream & os ) { os.nlOnOff$ = false; }
    231231
    232 void ends( ifstream & is ) {}
    233 
    234232bool eof( ifstream & is ) { return feof( (FILE *)(is.file$) ) != 0; }
    235233
     
    311309        } // if
    312310        va_end( args );
     311//      if ( len == 0 ) throw ExceptionInst( missing_data );
    313312        return len;
    314313} // fmt
  • libcfa/src/fstream.hfa

    r0030b508 rfc12f05  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Aug 18 10:41:15 2023
    13 // Update Count     : 258
     12// Last Modified On : Wed Oct 18 20:30:12 2023
     13// Update Count     : 261
    1414//
    1515
     
    117117void nlOn( ifstream & );
    118118void nlOff( ifstream & );
    119 void ends( ifstream & );
    120119int fmt( ifstream &, const char format[], ... ) __attribute__(( format(scanf, 2, 3) ));
     120ifstream & ungetc( ifstream & is, char c );
     121bool eof( ifstream & is );
    121122
    122123bool fail( ifstream & is );
    123124void clear( ifstream & );
    124 bool eof( ifstream & is );
    125125void open( ifstream & is, const char name[], const char mode[] ); // FIX ME: use default = "r"
    126126void open( ifstream & is, const char name[] );
    127127void close( ifstream & is );
    128 
    129128ifstream & read( ifstream & is, char data[], size_t size );
    130 ifstream & ungetc( ifstream & is, char c );
    131129
    132130void ?{}( ifstream & is );
  • libcfa/src/iostream.cfa

    r0030b508 rfc12f05  
    1 
    21//
    32// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
     
    1110// Created On       : Wed May 27 17:56:53 2015
    1211// Last Modified By : Peter A. Buhr
    13 // Last Modified On : Sun Oct  8 12:10:21 2023
    14 // Update Count     : 1564
     12// Last Modified On : Sat Nov 11 07:06:27 2023
     13// Update Count     : 1803
    1514//
    1615
     
    785784                return is;
    786785        } // ?|?
    787         ISTYPE_VOID_IMPL( bool & )
    788786
    789787        istype & ?|?( istype & is, char & c ) {
     
    797795                return is;
    798796        } // ?|?
    799         ISTYPE_VOID_IMPL( char & )
    800797
    801798        istype & ?|?( istype & is, signed char & sc ) {
     
    803800                return is;
    804801        } // ?|?
    805         ISTYPE_VOID_IMPL( signed char & )
    806802
    807803        istype & ?|?( istype & is, unsigned char & usc ) {
     
    809805                return is;
    810806        } // ?|?
    811         ISTYPE_VOID_IMPL( unsigned char & )
    812807
    813808        istype & ?|?( istype & is, short int & si ) {
     
    815810                return is;
    816811        } // ?|?
    817         ISTYPE_VOID_IMPL( short int & )
    818812
    819813        istype & ?|?( istype & is, unsigned short int & usi ) {
     
    821815                return is;
    822816        } // ?|?
    823         ISTYPE_VOID_IMPL( unsigned short int & )
    824817
    825818        istype & ?|?( istype & is, int & i ) {
     
    827820                return is;
    828821        } // ?|?
    829         ISTYPE_VOID_IMPL( int & )
    830822
    831823        istype & ?|?( istype & is, unsigned int & ui ) {
     
    833825                return is;
    834826        } // ?|?
    835         ISTYPE_VOID_IMPL( unsigned int & )
    836827
    837828        istype & ?|?( istype & is, long int & li ) {
     
    839830                return is;
    840831        } // ?|?
    841         ISTYPE_VOID_IMPL( long int & )
    842832
    843833        istype & ?|?( istype & is, unsigned long int & ulli ) {
     
    845835                return is;
    846836        } // ?|?
    847         ISTYPE_VOID_IMPL( unsigned long int & )
    848837
    849838        istype & ?|?( istype & is, long long int & lli ) {
     
    851840                return is;
    852841        } // ?|?
    853         ISTYPE_VOID_IMPL( long long int & )
    854842
    855843        istype & ?|?( istype & is, unsigned long long int & ulli ) {
     
    857845                return is;
    858846        } // ?|?
    859         ISTYPE_VOID_IMPL( unsigned long long int & )
    860847
    861848        #if defined( __SIZEOF_INT128__ )
     
    863850                return (istype &)(is | (unsigned int128 &)llli);
    864851        } // ?|?
    865         ISTYPE_VOID_IMPL( int128 & )
    866852
    867853        istype & ?|?( istype & is, unsigned int128 & ullli ) {
     
    880866                return is;
    881867        } // ?|?
    882         ISTYPE_VOID_IMPL( unsigned int128 & )
    883868        #endif // __SIZEOF_INT128__
    884869
     
    887872                return is;
    888873        } // ?|?
    889         ISTYPE_VOID_IMPL( float & )
    890874
    891875        istype & ?|?( istype & is, double & d ) {
     
    893877                return is;
    894878        } // ?|?
    895         ISTYPE_VOID_IMPL( double & )
    896879
    897880        istype & ?|?( istype & is, long double & ld ) {
     
    899882                return is;
    900883        } // ?|?
    901         ISTYPE_VOID_IMPL( long double & )
    902884
    903885        istype & ?|?( istype & is, float _Complex & fc ) {
     
    907889                return is;
    908890        } // ?|?
    909         ISTYPE_VOID_IMPL( float _Complex & )
    910891
    911892        istype & ?|?( istype & is, double _Complex & dc ) {
     
    915896                return is;
    916897        } // ?|?
    917         ISTYPE_VOID_IMPL( double _Complex & )
    918898
    919899        istype & ?|?( istype & is, long double _Complex & ldc ) {
     
    923903                return is;
    924904        } // ?|?
    925         ISTYPE_VOID_IMPL( long double _Complex & )
    926905
    927906        istype & ?|?( istype & is, const char fmt[] ) {
     
    929908                return is;
    930909        } // ?|?
    931         ISTYPE_VOID_IMPL( const char * )
    932910
    933911        // manipulators
     
    937915
    938916        void ?|?( istype & is, istype & (* manip)( istype & ) ) {
    939                 manip( is ); ends( is );
     917                manip( is );
    940918        } // ?|?
    941919
     
    966944                        char fmtstr[ sizeof("%*[]") + nscanset ];
    967945                        int pos = 0;
    968                         fmtstr[pos] = '%';                  pos += 1;
    969                         fmtstr[pos] = '*';                  pos += 1;
    970                         fmtstr[pos] = '[';                  pos += 1;
     946                        strcpy( &fmtstr[pos], "%*[" );  pos += 3;
    971947                        strcpy( &fmtstr[pos], f.scanset );  pos += nscanset;
    972                         fmtstr[pos] = ']';                  pos += 1;
    973                         fmtstr[pos] = '\0';
    974                         fmt( is, fmtstr, (void*)0 );  // last arg is dummy: suppress gcc warning
    975                 }
    976                 else for ( f.wd ) fmt( is, "%*c" );
     948                        strcpy( &fmtstr[pos], "]" );
     949                        fmt( is, fmtstr, "" );                                          // skip scanset
     950                } else {
     951                        char ch;
     952//                      fprintf( stderr, "skip " );
     953                        for ( f.wd ) {                                                          // skip N characters
     954                          if ( eof( is ) ) break;
     955                                fmt( is, "%c", &ch );
     956//                              fprintf( stderr, "`%c' ", ch );
     957                        } // for
     958                } // if
    977959                return is;
    978960        }
    979         ISTYPE_VOID_IMPL( _Istream_Cskip )
    980961
    981962        istype & ?|?( istype & is, _Istream_Cstr f ) {
    982                 const char * scanset = f.scanset;
     963                const char * scanset;
     964                size_t nscanset = 0;
    983965                if ( f.flags.delimiter ) scanset = f.delimiter; // getline ?
    984 
    985                 size_t len = 0;
    986                 if ( scanset ) len = strlen( scanset );
    987                 char fmtstr[len + 16];
    988                 int start = 1;
     966                else scanset = f.scanset;
     967                if ( scanset ) nscanset = strlen( scanset );
     968
     969                char fmtstr[nscanset + 32];                                             // storage for scanset and format codes
    989970                fmtstr[0] = '%';
    990                 if ( f.flags.ignore ) { fmtstr[1] = '*'; start += 1; }
    991                 // no maximum width necessary because text ignored => width is read width
    992                 if ( f.wd != -1 ) {
     971
     972                int pos = 1;
     973                int args;
     974                bool check = true;
     975
     976                if ( f.flags.ignore ) { check = false; fmtstr[1] = '*'; pos += 1; }
     977                int rwd = f.wd;
     978                if ( f.wd != -1 ) {                                                             // => just ignore versus ignore with width
    993979                        // wd is buffer bytes available (for input chars + null terminator)
    994980                        // rwd is count of input chars
    995                         int rwd;
    996                         if (f.flags.rwd) {
    997                                 verify (f.wd >= 0);
    998                                 rwd = f.wd;
     981                        // no maximum width necessary because text ignored => width is read width
     982                        if ( f.flags.rwd ) check = false;
     983                        else rwd = f.wd - 1;
     984                        pos += sprintf( &fmtstr[pos], "%d", rwd );
     985                } // if
     986
     987                if ( ! scanset ) {                                                              // %s, %*s, %ws, %*ws
     988//                      fprintf( stderr, "cstr %s\n", f.s );
     989                        strcpy( &fmtstr[pos], "s%n" );
     990                        int len = 0;                                                            // may not be set in fmt
     991                        if ( f.flags.ignore ) args = fmt( is, fmtstr, &len ); // no string argument for '*'
     992                        else args = fmt( is, fmtstr, f.s, &len );
     993//                      fprintf( stderr, "cstr %s %d %d %d %s\n", fmtstr, args, len, f.wd, f.s );
     994                        if ( check && len >= rwd && ! eof( is ) ) {     // might not fit
     995                                char peek;
     996                                fmt( is, "%c", &peek );                                 // check for whitespace terminator
     997//                              fprintf( stderr, "peek %d '%c'\n", args, peek );
     998                                if ( ! eof( is ) ) {
     999                                        ungetc( is, peek );
     1000                                        if ( ! isspace( peek ) ) throw ExceptionInst( cstring_length );
     1001                                } // if
     1002                        } // if
     1003                        // FIX ME: CFA strings need to be modified to NOT change the argument for this case, then this can be removed.
     1004                        if ( rwd > 0 && args == 0 ) f.s[0]= '\0';       // read failed => no pattern match => set string to null
     1005                } else {
     1006                        if ( f.flags.delimiter ) {                                      // getline
     1007//                              fprintf( stderr, "getline\n" );
     1008                                sprintf( &fmtstr[pos], "[%s%s]%%n", f.flags.inex ? "^" : "", scanset );
     1009//                              fprintf( stderr, "getline %s %d\n", fmtstr, f.wd );
     1010                                int len = 0;                                                    // may not be set in fmt
     1011                                if ( f.flags.ignore ) args = fmt( is, fmtstr, &len ); // no string argument for '*'
     1012                                else args = fmt( is, fmtstr, f.s, &len );
     1013//                              fprintf( stderr, "getline %s %d %d %d\n", fmtstr, args, f.wd, eof( is ) );
     1014                                if ( check && len == rwd && ! eof( is ) ) {     // might not fit
     1015                                        char peek;
     1016                                        fmt( is, "%c", &peek );                         // check for delimiter
     1017//                                      fprintf( stderr, "peek %d '%c'\n", args, peek );
     1018                                        if ( ! eof( is ) ) {
     1019                                                if ( peek != f.delimiter[0] ) {
     1020                                                        ungetc( is, peek );
     1021                                                        throw ExceptionInst( cstring_length );
     1022                                                } // if
     1023                                        } // if
     1024                                } else fmt( is, "%*c" );                                //  remove delimiter
    9991025                        } else {
    1000                                 verify (f.wd >= 1);
    1001                                 rwd = f.wd - 1;
     1026                                // incl %[xxx],  %*[xxx],  %w[xxx],  %*w[xxx]
     1027                                // excl %[^xxx], %*[^xxx], %w[^xxx], %*w[^xxx]
     1028                                sprintf( &fmtstr[pos], "[%s%s]%%n", f.flags.inex ? "^" : "", scanset );
     1029//                              fprintf( stderr, "incl/excl %s %d\n", fmtstr, f.wd );
     1030                                int len = 0;                                                    // may not be set in fmt
     1031                                if ( f.flags.ignore ) args = fmt( is, fmtstr, &len ); // no string argument for '*'
     1032                                else args = fmt( is, fmtstr, f.s, &len );
     1033//                              fprintf( stderr, "incl/excl %s \"%s\" %d %d %d %d %d %c\n", fmtstr, f.s, args, f.wd, len, eof( is ), check, f.s[f.wd] );
     1034                                if ( check && len == rwd && ! eof( is ) ) {     // might not fit
     1035//                                      fprintf( stderr, "overflow\n" );
     1036                                        char peek;
     1037                                        fmt( is, "%c", &peek );                         // check for whitespace terminator
     1038//                                      fprintf( stderr, "peek %d '%c'\n", args, peek );
     1039                                        if ( ! eof( is ) ) {
     1040                                                ungetc( is, peek );
     1041                                                if ( f.flags.inex ^ strchr( f.scanset, peek ) != 0p ) throw ExceptionInst( cstring_length );
     1042                                        } // if
     1043                                } // if
    10021044                        } // if
    1003                         start += sprintf( &fmtstr[start], "%d", rwd );
    1004                 }
    1005 
    1006                 if ( ! scanset ) {
    1007                         // %s, %*s, %ws, %*ws
    1008                         fmtstr[start] = 's'; fmtstr[start + 1] = '\0';
    1009                         // printf( "cstr %s\n", fmtstr );
    1010                 } else {
    1011                         // incl %[xxx],  %*[xxx],  %w[xxx],  %*w[xxx]
    1012                         // excl %[^xxx], %*[^xxx], %w[^xxx], %*w[^xxx]
    1013                         fmtstr[start] = '['; start += 1;
    1014                         if ( f.flags.inex ) { fmtstr[start] = '^'; start += 1; }
    1015                         strcpy( &fmtstr[start], scanset );                      // copy includes '\0'
    1016                         len += start;
    1017                         fmtstr[len] = ']'; fmtstr[len + 1] = '\0';
    1018                         // printf( "incl/excl %s\n", fmtstr );
    1019                 } // if
    1020 
    1021                 int check = f.wd - 2;
    1022                 if (! f.flags.ignore ) {
    1023                         f.s[0] = '\0';
    1024                         if ( ! f.flags.rwd ) f.s[check] = '\0';         // insert sentinel
    1025                 }
    1026                 len = fmt( is, fmtstr, f.s );
    1027                 //fprintf( stderr, "KK %s %zd %d %c %s\n", fmtstr, len, check, f.s[check], f.s );
    1028 
    1029                 if ( ! f.flags.ignore && ! f.flags.rwd && f.s[check] != '\0' ) { // sentinel overwritten ?
    1030                         // buffer filled, but would we have kept going?
    1031                         if ( ! eof( is ) ) {
    1032                                 char peek;
    1033                                 fmt( is, "%c", &peek );
    1034                                 ungetc( is, peek );
    1035                                 bool hasMore;
    1036                                 if (f.flags.delimiter) { // getline
    1037                                         hasMore = (peek != f.delimiter[0]);
    1038                                 } else if (f.scanset) { // incl/excl
    1039                                         bool peekMatch = strchr(f.scanset, peek) != 0p;
    1040                                         hasMore = f.flags.inex ? (!peekMatch) : (peekMatch);
    1041                                 } else { // %s
    1042                                         hasMore = !isspace(peek);
    1043                                 }
    1044                                 if (hasMore) throw (cstring_length){ &cstring_length_vt };
    1045                         } // if
    1046                 } // if
    1047 
    1048                 if ( f.flags.delimiter ) {                                              // getline ?
    1049                         if ( len == 0 ) f.s[0] = '\0';                          // empty read => argument unchanged => set empty
    1050                         if ( ! eof( is ) ) {                                            // ignore delimiter, may not be present because of width
    1051                                 char delimiter;
    1052                                 fmt( is, "%c", &delimiter );
    1053                                 if ( delimiter != f.delimiter[0] ) ungetc( is, delimiter );
    1054                         } // if
    1055                 } //if
    1056                 return is;
    1057         } // ?|?
    1058         ISTYPE_VOID_IMPL( _Istream_Cstr )
     1045                        if ( rwd > 0 && args == 0 ) f.s[0]= '\0';       // read failed => no pattern match => set string to null
     1046                } // if
     1047                if ( args == 1 && eof( is ) ) {                                 // data but scan ended at EOF
     1048//                      fprintf( stderr, "clear\n" );
     1049                        clear( is );                                                            // => reset EOF => detect again on next read
     1050                } // if
     1051                return is;
     1052        } // ?|?
    10591053
    10601054        istype & ?|?( istype & is, _Istream_Char f ) {
     
    10621056                return is;
    10631057        } // ?|?
    1064         ISTYPE_VOID_IMPL( _Istream_Char )
    10651058} // distribution
    10661059
     
    10791072                return is; \
    10801073        } /* ?|? */ \
    1081         ISTYPE_VOID_IMPL( _Istream_Manip(T) ) \
    10821074} // distribution
    10831075
     
    11071099                return is;
    11081100        } // ?|?
    1109         ISTYPE_VOID_IMPL( _Istream_Manip(float _Complex) )
    11101101
    11111102        istype & ?|?( istype & is, _Istream_Manip(double _Complex) dc ) {
     
    11181109                return is;
    11191110        } // ?|?
    1120         ISTYPE_VOID_IMPL( _Istream_Manip(double _Complex) )
    11211111
    11221112        istype & ?|?( istype & is, _Istream_Manip(long double _Complex) ldc ) {
     
    11291119                return is;
    11301120        } // ?|?
    1131         ISTYPE_VOID_IMPL( _Istream_Manip(long double _Complex) )
    11321121} // distribution
    11331122
  • libcfa/src/iostream.hfa

    r0030b508 rfc12f05  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Oct  8 12:02:55 2023
    13 // Update Count     : 568
     12// Last Modified On : Wed Oct 18 21:21:20 2023
     13// Update Count     : 583
    1414//
    1515
     
    306306// *********************************** istream ***********************************
    307307
    308 #define ISTYPE_VOID( T ) void ?|?( istype &, T )
    309 #define ISTYPE_VOID_IMPL( T ) \
    310         void ?|?( istype & is, T t ) { \
    311                 (istype &)(is | t); ends( is ); \
    312         } // ?|?
    313 
    314308forall( istype & )
    315309trait basic_istream {
     
    320314        void nlOn( istype & );                                                          // read newline
    321315        void nlOff( istype & );                                                         // scan newline
    322         void ends( istype & os );                                                       // end of output statement
    323316        int fmt( istype &, const char format[], ... ) __attribute__(( format(scanf, 2, 3) ));
    324317        istype & ungetc( istype &, char );
    325318        bool eof( istype & );
     319        void clear( istype & );
    326320}; // basic_istream
    327321
     
    329323trait istream {
    330324        bool fail( istype & );
    331         void clear( istype & );
     325        void open( istype & is, const char name[], const char mode[] );
    332326        void open( istype & is, const char name[] );
    333327        void close( istype & is );
     
    342336forall( istype & | basic_istream( istype ) ) {
    343337        istype & ?|?( istype &, bool & );
    344         ISTYPE_VOID( bool & );
    345338
    346339        istype & ?|?( istype &, char & );
    347         ISTYPE_VOID( char & );
    348340        istype & ?|?( istype &, signed char & );
    349         ISTYPE_VOID( signed char & );
    350341        istype & ?|?( istype &, unsigned char & );
    351         ISTYPE_VOID( unsigned char & );
    352342
    353343        istype & ?|?( istype &, short int & );
    354         ISTYPE_VOID( short int & );
    355344        istype & ?|?( istype &, unsigned short int & );
    356         ISTYPE_VOID( unsigned short int & );
    357345        istype & ?|?( istype &, int & );
    358         ISTYPE_VOID( int & );
    359346        istype & ?|?( istype &, unsigned int & );
    360         ISTYPE_VOID( unsigned int & );
    361347        istype & ?|?( istype &, long int & );
    362         ISTYPE_VOID( long int & );
    363348        istype & ?|?( istype &, unsigned long int & );
    364         ISTYPE_VOID( unsigned long int & );
    365349        istype & ?|?( istype &, long long int & );
    366         ISTYPE_VOID( long long int & );
    367350        istype & ?|?( istype &, unsigned long long int & );
    368         ISTYPE_VOID( unsigned long long int & );
    369351        #if defined( __SIZEOF_INT128__ )
    370352        istype & ?|?( istype &, int128 & );
    371         ISTYPE_VOID( int128 & );
    372353        istype & ?|?( istype &, unsigned int128 & );
    373         ISTYPE_VOID( unsigned int128 & );
    374354        #endif // __SIZEOF_INT128__
    375355
    376356        istype & ?|?( istype &, float & );
    377         ISTYPE_VOID( float & );
    378357        istype & ?|?( istype &, double & );
    379         ISTYPE_VOID( double & );
    380358        istype & ?|?( istype &, long double & );
    381         ISTYPE_VOID( long double & );
    382359
    383360        istype & ?|?( istype &, float _Complex & );
    384         ISTYPE_VOID( float _Complex & );
    385361        istype & ?|?( istype &, double _Complex & );
    386         ISTYPE_VOID( double _Complex & );
    387362        istype & ?|?( istype &, long double _Complex & );
    388         ISTYPE_VOID( long double _Complex & );
    389363
    390364        istype & ?|?( istype &, const char [] );
    391         ISTYPE_VOID( const char [] );
    392365
    393366        // manipulators
    394367        istype & ?|?( istype &, istype & (*)( istype & ) );
    395         ISTYPE_VOID( istype & (*)( istype & ) );
    396368        istype & nl( istype & is );
    397369        istype & nlOn( istype & );
     
    402374
    403375ExceptionDecl( cstring_length );
     376ExceptionDecl( missing_data );
    404377
    405378// *********************************** manipulators ***********************************
    406379
     380// skip does not compose with other C string manipulators.
    407381struct _Istream_Cskip {
    408382        const char * scanset;
     
    416390forall( istype & | basic_istream( istype ) ) {
    417391        istype & ?|?( istype & is, _Istream_Cskip f );
    418         ISTYPE_VOID( _Istream_Cskip );
    419392}
    420393
     
    458431forall( istype & | basic_istream( istype ) ) {
    459432        istype & ?|?( istype & is, _Istream_Cstr f );
    460         ISTYPE_VOID( _Istream_Cstr );
    461433}
    462434
     
    471443forall( istype & | basic_istream( istype ) ) {
    472444        istype & ?|?( istype & is, _Istream_Char f );
    473         ISTYPE_VOID( _Istream_Char );
    474445}
    475446
     
    490461forall( istype & | basic_istream( istype ) ) { \
    491462        istype & ?|?( istype & is, _Istream_Manip(T) f ); \
    492         ISTYPE_VOID( _Istream_Manip(T) ); \
    493463} // ?|?
    494464
Note: See TracChangeset for help on using the changeset viewer.