- Timestamp:
- Nov 13, 2023, 3:43:43 AM (2 years ago)
- 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. - Location:
- libcfa
- Files:
-
- 14 edited
- 3 moved
-
prelude/Makefile.am (modified) (5 diffs)
-
prelude/bootloader.cfa (moved) (moved from libcfa/prelude/bootloader.cf )
-
prelude/prelude.old.cfa (moved) (moved from libcfa/prelude/prelude.old.cf )
-
prelude/prototypes.awk (modified) (2 diffs)
-
prelude/sync-builtins.cfa (moved) (moved from libcfa/prelude/sync-builtins.cf )
-
src/Makefile.am (modified) (3 diffs)
-
src/collections/string.cfa (modified) (2 diffs)
-
src/collections/string_res.cfa (modified) (5 diffs)
-
src/concurrency/channel.hfa (modified) (2 diffs)
-
src/concurrency/cofor.cfa (modified) (3 diffs)
-
src/concurrency/cofor.hfa (modified) (3 diffs)
-
src/concurrency/kernel.hfa (modified) (1 diff)
-
src/concurrency/locks.hfa (modified) (1 diff)
-
src/fstream.cfa (modified) (3 diffs)
-
src/fstream.hfa (modified) (2 diffs)
-
src/iostream.cfa (modified) (30 diffs)
-
src/iostream.hfa (modified) (10 diffs)
Legend:
- Unmodified
- Added
- Removed
-
libcfa/prelude/Makefile.am
r0030b508 rfc12f05 11 11 ## Created On : Sun May 31 08:54:01 2015 12 12 ## Last Modified By : Peter A. Buhr 13 ## Last Modified On : Thu Jan 13 17:06:27 202214 ## Update Count : 2 1513 ## Last Modified On : Wed Nov 1 21:09:25 2023 14 ## Update Count : 221 15 15 ############################################################################### 16 16 … … 21 21 # put into lib for now 22 22 cfalibdir = ${CFA_LIBDIR} 23 cfalib_DATA = gcc-builtins.cf builtins.cf extras.cfprelude.cfa bootloader.c defines.hfa23 cfalib_DATA = gcc-builtins.cfa builtins.cfa extras.cfa prelude.cfa bootloader.c defines.hfa 24 24 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.cf25 EXTRA_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 26 26 27 27 CC = @LOCAL_CFACC@ … … 36 36 37 37 # create extra forward types/declarations to reduce inclusion of library files 38 extras.cf : ${srcdir}/extras.regx ${srcdir}/extras.c38 extras.cfa : ${srcdir}/extras.regx ${srcdir}/extras.c 39 39 @echo '# 2 "${@}" // needed for error messages from this file' > ${@} 40 40 ${AM_V_GEN}gcc ${AM_CFLAGS} -E ${srcdir}/extras.c | grep -f ${srcdir}/extras.regx >> ${@} … … 42 42 43 43 # create forward declarations for gcc builtins 44 gcc-builtins.cf : gcc-builtins.c ${srcdir}/prototypes.sed44 gcc-builtins.cfa : gcc-builtins.c ${srcdir}/prototypes.sed 45 45 @echo '# 2 "${@}" // needed for error messages from this file' > ${@} 46 46 ${AM_V_GEN}gcc -I${srcdir} -E -P $< | sed -r -f ${srcdir}/prototypes.sed >> ${@} 47 47 48 gcc-builtins.c : ${srcdir}/builtins.def ${srcdir}/prototypes.awk ${srcdir}/sync-builtins.cf ${srcdir}/prototypes.c48 gcc-builtins.c : ${srcdir}/builtins.def ${srcdir}/prototypes.awk ${srcdir}/sync-builtins.cfa ${srcdir}/prototypes.c 49 49 ${AM_V_GEN}gcc -I${srcdir} -E ${srcdir}/prototypes.c | awk -f ${srcdir}/prototypes.awk > ${@} 50 50 … … 59 59 60 60 # create forward declarations for cfa builtins 61 builtins.cf : builtins.c @LOCAL_CFACC@61 builtins.cfa : builtins.c @LOCAL_CFACC@ 62 62 ${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.Po63 ${AM_V_at}sed -i 's/builtins.o/builtins.cfa/g' $(DEPDIR)/builtins.Po 64 64 65 65 include $(DEPDIR)/builtins.Po 66 66 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 install67 bootloader.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 69 69 70 70 maintainer-clean-local : 71 71 rm -rf $(DEPDIR) 72 72 73 MOSTLYCLEANFILES = bootloader.c builtins.cf extras.cf gcc-builtins.c gcc-builtins.cfprelude.cfa73 MOSTLYCLEANFILES = bootloader.c builtins.cfa extras.cfa gcc-builtins.c gcc-builtins.cfa prelude.cfa 74 74 DISTCLEANFILES = $(DEPDIR)/builtins.Po 75 75 MAINTAINERCLEANFILES = ${addprefix ${libdir}/,${cfalib_DATA}} ${addprefix ${libdir}/,${lib_LIBRARIES}} 76 76 77 77 if ENABLE_DISTCC 78 distribution: @LOCAL_CFACC@ @LOCAL_CC1@ @CFACPP@ defines.hfa gcc-builtins.cf builtins.cf extras.cfprelude.cfa bootloader.c $(srcdir)/../../tools/build/push2dist.sh78 distribution: @LOCAL_CFACC@ @LOCAL_CC1@ @CFACPP@ defines.hfa gcc-builtins.cfa builtins.cfa extras.cfa prelude.cfa bootloader.c $(srcdir)/../../tools/build/push2dist.sh 79 79 ${AM_V_GEN}$(srcdir)/../../tools/build/push2dist.sh @CFADIR_HASH@ @DIST_BWLIMIT@ 80 80 @echo "Dummy file to track distribution to remote hosts" > ${@} -
libcfa/prelude/prototypes.awk
r0030b508 rfc12f05 10 10 # Created On : Sat May 16 07:57:37 2015 11 11 # Last Modified By : Peter A. Buhr 12 # Last Modified On : Sat Feb 8 09:46:58 202013 # Update Count : 3 612 # Last Modified On : Wed Nov 1 20:44:04 2023 13 # Update Count : 37 14 14 # 15 15 … … 150 150 # extras 151 151 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" ); 153 153 printf( "extern const char *__PRETTY_FUNCTION__;\n" ); 154 154 printf( "float _Complex __builtin_complex( float, float );\n" ); -
libcfa/src/Makefile.am
r0030b508 rfc12f05 11 11 ## Created On : Sun May 31 08:54:01 2015 12 12 ## Last Modified By : Peter A. Buhr 13 ## Last Modified On : Mon Sep 18 17:06:56202314 ## Update Count : 26 413 ## Last Modified On : Wed Nov 1 19:03:42 2023 14 ## Update Count : 266 15 15 ############################################################################### 16 16 … … 195 195 if ENABLE_DISTCC 196 196 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.sh197 ../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 198 198 @+make -C ../prelude distribution 199 199 … … 202 202 endif ENABLE_DISTCC 203 203 204 prelude.o : prelude.cfa extras.cf gcc-builtins.cf builtins.cf@LOCAL_CFACC@ @CFACPP@204 prelude.o : prelude.cfa extras.cfa gcc-builtins.cfa builtins.cfa @LOCAL_CFACC@ @CFACPP@ 205 205 ${AM_V_GEN}$(CFACOMPILE) -quiet -XCFA,-l ${<} -c -fvisibility=default -o ${@} 206 206 207 prelude.lo: prelude.cfa extras.cf gcc-builtins.cf builtins.cf@LOCAL_CFACC@ @CFACPP@207 prelude.lo: prelude.cfa extras.cfa gcc-builtins.cfa builtins.cfa @LOCAL_CFACC@ @CFACPP@ 208 208 ${AM_V_GEN}$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile \ 209 209 $(CFACOMPILE) -quiet -XCFA,-l ${<} -c -fvisibility=default -o ${@} -
libcfa/src/collections/string.cfa
r0030b508 rfc12f05 10 10 // Created On : Fri Sep 03 11:00:00 2021 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Sep 2 12:05:57202313 // Update Count : 20 612 // Last Modified On : Wed Oct 18 21:52:09 2023 13 // Update Count : 208 14 14 // 15 15 … … 138 138 139 139 void ?|?( ifstream & in, _Istream_Sstr f ) { 140 (ifstream &)(in | f); ends( in );140 (ifstream &)(in | f); 141 141 } 142 142 -
libcfa/src/collections/string_res.cfa
r0030b508 rfc12f05 10 10 // Created On : Fri Sep 03 11:00:00 2021 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Aug 14 18:06:01202313 // Update Count : 1 212 // Last Modified On : Wed Oct 18 21:54:54 2023 13 // Update Count : 15 14 14 // 15 15 … … 236 236 // get bytes 237 237 try { 238 *(temp.Handle.ulink->EndVbyte) = '\0'; // pre-assign empty cstring 238 239 in | wdi( lenReadable, temp.Handle.ulink->EndVbyte ); 239 240 } catch (cstring_length*) { … … 247 248 } 248 249 249 s = temp;250 if ( temp.Handle.lnth > 0 ) s = temp; 250 251 return in; 251 252 } 252 253 253 254 void ?|?( ifstream & in, string_res & this ) { 254 (ifstream &)(in | this); ends( in );255 (ifstream &)(in | this); 255 256 } 256 257 … … 268 269 cstr[wd] = '\0'; // guard null terminate string 269 270 try { 271 cstr[0] = '\0'; // pre-assign as empty cstring 270 272 is | cf; 271 273 } catch( cstring_length * ) { 272 274 cont = true; 273 275 } 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 } 275 280 } // try 276 281 for ( ; cont; ) { // overflow read ? 277 282 cont = false; 278 283 try { 284 cstr[0] = '\0'; // pre-assign as empty cstring 279 285 is | cf; 280 286 } catch( cstring_length * ) { 281 287 cont = true; // continue not allowed 282 288 } 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 } 284 293 } // try 285 294 } // for … … 288 297 289 298 void ?|?( ifstream & in, _Istream_Rstr f ) { 290 (ifstream &)(in | f); ends( in );299 (ifstream &)(in | f); 291 300 } 292 301 -
libcfa/src/concurrency/channel.hfa
r0030b508 rfc12f05 130 130 static inline void __cons_handoff( channel(T) & chan, T & elem ) with(chan) { 131 131 memcpy( cons`first.extra, (void *)&elem, sizeof(T) ); // do waiting consumer work 132 __atomic_thread_fence( __ATOMIC_SEQ_CST );133 132 wake_one( cons ); 134 133 } … … 137 136 static inline void __prods_handoff( channel(T) & chan, T & retval ) with(chan) { 138 137 memcpy( (void *)&retval, prods`first.extra, sizeof(T) ); 139 __atomic_thread_fence( __ATOMIC_SEQ_CST );140 138 wake_one( prods ); 141 139 } -
libcfa/src/concurrency/cofor.cfa
r0030b508 rfc12f05 4 4 // cofor ( uC++ COFOR ) 5 5 6 thread cofor_ runner{6 thread cofor_task { 7 7 ssize_t low, high; 8 8 __cofor_body_t loop_body; 9 9 }; 10 10 11 static void ?{}( cofor_ runner& this, ssize_t low, ssize_t high, __cofor_body_t loop_body ) {11 static void ?{}( cofor_task & this, ssize_t low, ssize_t high, __cofor_body_t loop_body ) { 12 12 this.low = low; 13 13 this.high = high; … … 15 15 } 16 16 17 void main( cofor_ runner& this ) with( this ) {17 void main( cofor_task & this ) with( this ) { 18 18 for ( ssize_t i = low; i < high; i++ ) 19 19 loop_body(i); … … 29 29 ssize_t i = 0; 30 30 ssize_t stride_iter = low; 31 cofor_ runner* runners[ threads ];31 cofor_task * runners[ threads ]; 32 32 for ( i; threads ) { 33 33 runners[i] = alloc(); -
libcfa/src/concurrency/cofor.hfa
r0030b508 rfc12f05 1 1 #include <thread.hfa> 2 #include <locks.hfa> 3 #include <list.hfa> 2 4 3 5 ////////////////////////////////////////////////////////////////////////////////////////// … … 14 16 __Cofor__( low, high, __CFA_loopLambda__ ); \ 15 17 } 18 19 struct runner_node { 20 void * value; 21 inline dlink(runner_node); 22 }; 23 P9_EMBEDDED( runner_node, dlink(runner_node) ) 24 25 thread cofor_runner { 26 go_mutex mutex_lock; // MX lock 27 dlist( runner_node ) items; 28 void (*func)(void *); 29 volatile bool done; 30 }; 31 32 void ?{}( cofor_runner & this ) { this.done = false; } 33 34 void 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 45 void start_runners( cofor_runner * thds, unsigned nprocs, void (*func)(void *) ) { 46 for ( i; nprocs ) { 47 thds[i].func = func; 48 } 49 } 50 51 void end_runners( cofor_runner * thds, unsigned nprocs ) { 52 for ( i; nprocs ) { 53 thds[i].done = true; 54 } 55 } 56 57 void 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 } 16 66 17 67 ////////////////////////////////////////////////////////////////////////////////////////// … … 42 92 delete( this.runner ); 43 93 } 44 -
libcfa/src/concurrency/kernel.hfa
r0030b508 rfc12f05 303 303 // gets the number of constructed processors on the cluster 304 304 static inline unsigned get_proc_count( cluster & this ) { return this.procs.constructed; } 305 static inline unsigned get_proc_count() { return publicTLS_get( this_processor )->cltr->procs.constructed; } 305 306 306 307 // set the number of internal processors -
libcfa/src/concurrency/locks.hfa
r0030b508 rfc12f05 182 182 static inline void lock( mcs_spin_lock & l, mcs_spin_node & n ) { 183 183 n.locked = true; 184 185 #if defined(__ARM_ARCH) 186 __asm__ __volatile__ ( "DMB ISH" ::: ); 187 #endif 188 184 189 mcs_spin_node * prev = __atomic_exchange_n(&l.queue.tail, &n, __ATOMIC_SEQ_CST); 185 190 if( prev == 0p ) return; 186 191 prev->next = &n; 192 193 #if defined(__ARM_ARCH) 194 __asm__ __volatile__ ( "DMB ISH" ::: ); 195 #endif 196 187 197 while( __atomic_load_n(&n.locked, __ATOMIC_RELAXED) ) Pause(); 198 199 #if defined(__ARM_ARCH) 200 __asm__ __volatile__ ( "DMB ISH" ::: ); 201 #endif 188 202 } 189 203 190 204 static inline void unlock(mcs_spin_lock & l, mcs_spin_node & n) { 205 #if defined(__ARM_ARCH) 206 __asm__ __volatile__ ( "DMB ISH" ::: ); 207 #endif 208 191 209 mcs_spin_node * n_ptr = &n; 192 210 if (__atomic_compare_exchange_n(&l.queue.tail, &n_ptr, 0p, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) return; 193 211 while (__atomic_load_n(&n.next, __ATOMIC_RELAXED) == 0p) Pause(); 212 213 #if defined(__ARM_ARCH) 214 __asm__ __volatile__ ( "DMB ISH" ::: ); 215 #endif 216 194 217 n.next->locked = false; 195 218 } -
libcfa/src/fstream.cfa
r0030b508 rfc12f05 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Aug 18 10:41:17202313 // Update Count : 54 112 // Last Modified On : Wed Oct 18 22:05:54 2023 13 // Update Count : 549 14 14 // 15 15 … … 230 230 void nlOff( ifstream & os ) { os.nlOnOff$ = false; } 231 231 232 void ends( ifstream & is ) {}233 234 232 bool eof( ifstream & is ) { return feof( (FILE *)(is.file$) ) != 0; } 235 233 … … 311 309 } // if 312 310 va_end( args ); 311 // if ( len == 0 ) throw ExceptionInst( missing_data ); 313 312 return len; 314 313 } // fmt -
libcfa/src/fstream.hfa
r0030b508 rfc12f05 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Aug 18 10:41:15202313 // Update Count : 2 5812 // Last Modified On : Wed Oct 18 20:30:12 2023 13 // Update Count : 261 14 14 // 15 15 … … 117 117 void nlOn( ifstream & ); 118 118 void nlOff( ifstream & ); 119 void ends( ifstream & );120 119 int fmt( ifstream &, const char format[], ... ) __attribute__(( format(scanf, 2, 3) )); 120 ifstream & ungetc( ifstream & is, char c ); 121 bool eof( ifstream & is ); 121 122 122 123 bool fail( ifstream & is ); 123 124 void clear( ifstream & ); 124 bool eof( ifstream & is );125 125 void open( ifstream & is, const char name[], const char mode[] ); // FIX ME: use default = "r" 126 126 void open( ifstream & is, const char name[] ); 127 127 void close( ifstream & is ); 128 129 128 ifstream & read( ifstream & is, char data[], size_t size ); 130 ifstream & ungetc( ifstream & is, char c );131 129 132 130 void ?{}( ifstream & is ); -
libcfa/src/iostream.cfa
r0030b508 rfc12f05 1 2 1 // 3 2 // Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo … … 11 10 // Created On : Wed May 27 17:56:53 2015 12 11 // Last Modified By : Peter A. Buhr 13 // Last Modified On : S un Oct 8 12:10:21202314 // Update Count : 1 56412 // Last Modified On : Sat Nov 11 07:06:27 2023 13 // Update Count : 1803 15 14 // 16 15 … … 785 784 return is; 786 785 } // ?|? 787 ISTYPE_VOID_IMPL( bool & )788 786 789 787 istype & ?|?( istype & is, char & c ) { … … 797 795 return is; 798 796 } // ?|? 799 ISTYPE_VOID_IMPL( char & )800 797 801 798 istype & ?|?( istype & is, signed char & sc ) { … … 803 800 return is; 804 801 } // ?|? 805 ISTYPE_VOID_IMPL( signed char & )806 802 807 803 istype & ?|?( istype & is, unsigned char & usc ) { … … 809 805 return is; 810 806 } // ?|? 811 ISTYPE_VOID_IMPL( unsigned char & )812 807 813 808 istype & ?|?( istype & is, short int & si ) { … … 815 810 return is; 816 811 } // ?|? 817 ISTYPE_VOID_IMPL( short int & )818 812 819 813 istype & ?|?( istype & is, unsigned short int & usi ) { … … 821 815 return is; 822 816 } // ?|? 823 ISTYPE_VOID_IMPL( unsigned short int & )824 817 825 818 istype & ?|?( istype & is, int & i ) { … … 827 820 return is; 828 821 } // ?|? 829 ISTYPE_VOID_IMPL( int & )830 822 831 823 istype & ?|?( istype & is, unsigned int & ui ) { … … 833 825 return is; 834 826 } // ?|? 835 ISTYPE_VOID_IMPL( unsigned int & )836 827 837 828 istype & ?|?( istype & is, long int & li ) { … … 839 830 return is; 840 831 } // ?|? 841 ISTYPE_VOID_IMPL( long int & )842 832 843 833 istype & ?|?( istype & is, unsigned long int & ulli ) { … … 845 835 return is; 846 836 } // ?|? 847 ISTYPE_VOID_IMPL( unsigned long int & )848 837 849 838 istype & ?|?( istype & is, long long int & lli ) { … … 851 840 return is; 852 841 } // ?|? 853 ISTYPE_VOID_IMPL( long long int & )854 842 855 843 istype & ?|?( istype & is, unsigned long long int & ulli ) { … … 857 845 return is; 858 846 } // ?|? 859 ISTYPE_VOID_IMPL( unsigned long long int & )860 847 861 848 #if defined( __SIZEOF_INT128__ ) … … 863 850 return (istype &)(is | (unsigned int128 &)llli); 864 851 } // ?|? 865 ISTYPE_VOID_IMPL( int128 & )866 852 867 853 istype & ?|?( istype & is, unsigned int128 & ullli ) { … … 880 866 return is; 881 867 } // ?|? 882 ISTYPE_VOID_IMPL( unsigned int128 & )883 868 #endif // __SIZEOF_INT128__ 884 869 … … 887 872 return is; 888 873 } // ?|? 889 ISTYPE_VOID_IMPL( float & )890 874 891 875 istype & ?|?( istype & is, double & d ) { … … 893 877 return is; 894 878 } // ?|? 895 ISTYPE_VOID_IMPL( double & )896 879 897 880 istype & ?|?( istype & is, long double & ld ) { … … 899 882 return is; 900 883 } // ?|? 901 ISTYPE_VOID_IMPL( long double & )902 884 903 885 istype & ?|?( istype & is, float _Complex & fc ) { … … 907 889 return is; 908 890 } // ?|? 909 ISTYPE_VOID_IMPL( float _Complex & )910 891 911 892 istype & ?|?( istype & is, double _Complex & dc ) { … … 915 896 return is; 916 897 } // ?|? 917 ISTYPE_VOID_IMPL( double _Complex & )918 898 919 899 istype & ?|?( istype & is, long double _Complex & ldc ) { … … 923 903 return is; 924 904 } // ?|? 925 ISTYPE_VOID_IMPL( long double _Complex & )926 905 927 906 istype & ?|?( istype & is, const char fmt[] ) { … … 929 908 return is; 930 909 } // ?|? 931 ISTYPE_VOID_IMPL( const char * )932 910 933 911 // manipulators … … 937 915 938 916 void ?|?( istype & is, istype & (* manip)( istype & ) ) { 939 manip( is ); ends( is );917 manip( is ); 940 918 } // ?|? 941 919 … … 966 944 char fmtstr[ sizeof("%*[]") + nscanset ]; 967 945 int pos = 0; 968 fmtstr[pos] = '%'; pos += 1; 969 fmtstr[pos] = '*'; pos += 1; 970 fmtstr[pos] = '['; pos += 1; 946 strcpy( &fmtstr[pos], "%*[" ); pos += 3; 971 947 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 977 959 return is; 978 960 } 979 ISTYPE_VOID_IMPL( _Istream_Cskip )980 961 981 962 istype & ?|?( istype & is, _Istream_Cstr f ) { 982 const char * scanset = f.scanset; 963 const char * scanset; 964 size_t nscanset = 0; 983 965 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 989 970 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 993 979 // wd is buffer bytes available (for input chars + null terminator) 994 980 // 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 999 1025 } 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 1002 1044 } // 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 } // ?|? 1059 1053 1060 1054 istype & ?|?( istype & is, _Istream_Char f ) { … … 1062 1056 return is; 1063 1057 } // ?|? 1064 ISTYPE_VOID_IMPL( _Istream_Char )1065 1058 } // distribution 1066 1059 … … 1079 1072 return is; \ 1080 1073 } /* ?|? */ \ 1081 ISTYPE_VOID_IMPL( _Istream_Manip(T) ) \1082 1074 } // distribution 1083 1075 … … 1107 1099 return is; 1108 1100 } // ?|? 1109 ISTYPE_VOID_IMPL( _Istream_Manip(float _Complex) )1110 1101 1111 1102 istype & ?|?( istype & is, _Istream_Manip(double _Complex) dc ) { … … 1118 1109 return is; 1119 1110 } // ?|? 1120 ISTYPE_VOID_IMPL( _Istream_Manip(double _Complex) )1121 1111 1122 1112 istype & ?|?( istype & is, _Istream_Manip(long double _Complex) ldc ) { … … 1129 1119 return is; 1130 1120 } // ?|? 1131 ISTYPE_VOID_IMPL( _Istream_Manip(long double _Complex) )1132 1121 } // distribution 1133 1122 -
libcfa/src/iostream.hfa
r0030b508 rfc12f05 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Oct 8 12:02:55202313 // Update Count : 5 6812 // Last Modified On : Wed Oct 18 21:21:20 2023 13 // Update Count : 583 14 14 // 15 15 … … 306 306 // *********************************** istream *********************************** 307 307 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 314 308 forall( istype & ) 315 309 trait basic_istream { … … 320 314 void nlOn( istype & ); // read newline 321 315 void nlOff( istype & ); // scan newline 322 void ends( istype & os ); // end of output statement323 316 int fmt( istype &, const char format[], ... ) __attribute__(( format(scanf, 2, 3) )); 324 317 istype & ungetc( istype &, char ); 325 318 bool eof( istype & ); 319 void clear( istype & ); 326 320 }; // basic_istream 327 321 … … 329 323 trait istream { 330 324 bool fail( istype & ); 331 void clear( istype &);325 void open( istype & is, const char name[], const char mode[] ); 332 326 void open( istype & is, const char name[] ); 333 327 void close( istype & is ); … … 342 336 forall( istype & | basic_istream( istype ) ) { 343 337 istype & ?|?( istype &, bool & ); 344 ISTYPE_VOID( bool & );345 338 346 339 istype & ?|?( istype &, char & ); 347 ISTYPE_VOID( char & );348 340 istype & ?|?( istype &, signed char & ); 349 ISTYPE_VOID( signed char & );350 341 istype & ?|?( istype &, unsigned char & ); 351 ISTYPE_VOID( unsigned char & );352 342 353 343 istype & ?|?( istype &, short int & ); 354 ISTYPE_VOID( short int & );355 344 istype & ?|?( istype &, unsigned short int & ); 356 ISTYPE_VOID( unsigned short int & );357 345 istype & ?|?( istype &, int & ); 358 ISTYPE_VOID( int & );359 346 istype & ?|?( istype &, unsigned int & ); 360 ISTYPE_VOID( unsigned int & );361 347 istype & ?|?( istype &, long int & ); 362 ISTYPE_VOID( long int & );363 348 istype & ?|?( istype &, unsigned long int & ); 364 ISTYPE_VOID( unsigned long int & );365 349 istype & ?|?( istype &, long long int & ); 366 ISTYPE_VOID( long long int & );367 350 istype & ?|?( istype &, unsigned long long int & ); 368 ISTYPE_VOID( unsigned long long int & );369 351 #if defined( __SIZEOF_INT128__ ) 370 352 istype & ?|?( istype &, int128 & ); 371 ISTYPE_VOID( int128 & );372 353 istype & ?|?( istype &, unsigned int128 & ); 373 ISTYPE_VOID( unsigned int128 & );374 354 #endif // __SIZEOF_INT128__ 375 355 376 356 istype & ?|?( istype &, float & ); 377 ISTYPE_VOID( float & );378 357 istype & ?|?( istype &, double & ); 379 ISTYPE_VOID( double & );380 358 istype & ?|?( istype &, long double & ); 381 ISTYPE_VOID( long double & );382 359 383 360 istype & ?|?( istype &, float _Complex & ); 384 ISTYPE_VOID( float _Complex & );385 361 istype & ?|?( istype &, double _Complex & ); 386 ISTYPE_VOID( double _Complex & );387 362 istype & ?|?( istype &, long double _Complex & ); 388 ISTYPE_VOID( long double _Complex & );389 363 390 364 istype & ?|?( istype &, const char [] ); 391 ISTYPE_VOID( const char [] );392 365 393 366 // manipulators 394 367 istype & ?|?( istype &, istype & (*)( istype & ) ); 395 ISTYPE_VOID( istype & (*)( istype & ) );396 368 istype & nl( istype & is ); 397 369 istype & nlOn( istype & ); … … 402 374 403 375 ExceptionDecl( cstring_length ); 376 ExceptionDecl( missing_data ); 404 377 405 378 // *********************************** manipulators *********************************** 406 379 380 // skip does not compose with other C string manipulators. 407 381 struct _Istream_Cskip { 408 382 const char * scanset; … … 416 390 forall( istype & | basic_istream( istype ) ) { 417 391 istype & ?|?( istype & is, _Istream_Cskip f ); 418 ISTYPE_VOID( _Istream_Cskip );419 392 } 420 393 … … 458 431 forall( istype & | basic_istream( istype ) ) { 459 432 istype & ?|?( istype & is, _Istream_Cstr f ); 460 ISTYPE_VOID( _Istream_Cstr );461 433 } 462 434 … … 471 443 forall( istype & | basic_istream( istype ) ) { 472 444 istype & ?|?( istype & is, _Istream_Char f ); 473 ISTYPE_VOID( _Istream_Char );474 445 } 475 446 … … 490 461 forall( istype & | basic_istream( istype ) ) { \ 491 462 istype & ?|?( istype & is, _Istream_Manip(T) f ); \ 492 ISTYPE_VOID( _Istream_Manip(T) ); \493 463 } // ?|? 494 464
Note:
See TracChangeset
for help on using the changeset viewer.