@@ -198,8 +198,9 @@ char *cb_single_jar_name = NULL;
198198int cb_flag_info_json = 0 ;
199199char * cb_info_json_dir = NULL ;
200200
201- #define PROGRAM_ID_LIST_MAX_LEN 1024
201+ #define PROGRAM_ID_LIST_MAX_LEN (65536)
202202char * program_id_list [PROGRAM_ID_LIST_MAX_LEN ];
203+ int program_id_list_index = 0 ;
203204
204205#ifdef _MSC_VER
205206#if _MSC_VER >= 1400
@@ -1822,10 +1823,7 @@ static int process_translate(struct filename *fn) {
18221823 }
18231824
18241825 /* translate to Java */
1825- for (i = 0 ; i < PROGRAM_ID_LIST_MAX_LEN ; ++ i ) {
1826- program_id_list [i ] = NULL ;
1827- }
1828- codegen (p , 0 , program_id_list ,
1826+ codegen (p , 0 , & program_id_list [program_id_list_index ++ ],
18291827 java_source_dir == NULL ? (char * )"./" : java_source_dir , fn -> source );
18301828
18311829 return 0 ;
@@ -1843,104 +1841,106 @@ static void package_name_to_path(char *buff, char *package_name) {
18431841 }
18441842}
18451843
1846- static int process_compile (struct filename * fn ) {
1847- char buff [COB_MEDIUM_BUFF ];
1844+ static int process_compile_all (void ) {
1845+ #define BUFF_SIZE (COB_LARGE_BUFF * 32)
1846+ char buff [BUFF_SIZE ];
18481847 char buff2 [COB_SMALL_BUFF ];
1849- char name [COB_MEDIUM_BUFF ];
18501848 int ret = 0 ;
18511849#ifdef _WIN32
18521850 char current_dir [] = ".\\" ;
1853- char remove_cmd [] = "del" ;
18541851#else
18551852 char current_dir [] = "./" ;
1856- char remove_cmd [] = "rm -rf" ;
18571853#endif
18581854
1859- if (output_name ) {
1860- strcpy (name , output_name );
1861- } else {
1862- file_basename (fn -> source , name );
1863- }
1864-
18651855 char * output_name_a = output_name == NULL ? current_dir : output_name ;
18661856 char * java_source_dir_a =
18671857 java_source_dir == NULL ? current_dir : java_source_dir ;
18681858
1859+ /* Build list of Java files to compile */
1860+ /* Reserve space for "javac ... -encoding ... -d ... " prefix (at least 1024
1861+ * bytes) */
1862+ #define JAVA_FILES_MAX_LEN (BUFF_SIZE / 2)
1863+ char java_files [JAVA_FILES_MAX_LEN ] = "" ;
18691864 char * * program_id ;
18701865 for (program_id = program_id_list ; * program_id ; ++ program_id ) {
1871- snprintf (buff , COB_MEDIUM_BUFF , "javac %s -encoding %s -d %s %s/%s.java" ,
1872- cob_java_flags , JAVAC_ENCODING , output_name_a , java_source_dir_a ,
1873- * program_id );
1874- ret = process (buff );
1866+ if (strlen (java_files ) + strlen (java_source_dir_a ) + strlen (* program_id ) +
1867+ 10 >
1868+ JAVA_FILES_MAX_LEN ) {
1869+ fprintf (stderr , "Too many Java files to compile at once\n" );
1870+ return -1 ;
1871+ }
1872+ strcat (java_files , java_source_dir_a );
1873+ strcat (java_files , "/" );
1874+ strcat (java_files , * program_id );
1875+ strcat (java_files , ".java " );
1876+ }
1877+ #undef JAVA_FILES_MAX_LEN
18751878
1876- if (ret ) {
1877- return ret ;
1879+ /* Compile all Java files at once */
1880+ snprintf (buff , BUFF_SIZE , "javac %s -encoding %s -d %s %s" , cob_java_flags ,
1881+ JAVAC_ENCODING , output_name_a , java_files );
1882+ ret = process (buff );
1883+ if (ret ) {
1884+ return ret ;
1885+ }
1886+
1887+ /* Create jar files if cb_flag_jar is set */
1888+ if (cb_flag_jar ) {
1889+ char * package_dir ;
1890+ if (cb_java_package_name ) {
1891+ package_name_to_path (buff2 , cb_java_package_name );
1892+ package_dir = buff2 ;
1893+ } else {
1894+ package_dir = (char * )"." ;
18781895 }
1879- if (cb_flag_jar ) {
1880- char * package_dir ;
1881- if (cb_java_package_name ) {
1882- package_name_to_path (buff2 , cb_java_package_name );
1883- package_dir = buff2 ;
1884- } else {
1885- package_dir = (char * )"." ;
1886- }
1887- snprintf (buff , COB_MEDIUM_BUFF ,
1888- "cd %s && jar --create --main-class=%s --file=%s.jar %s/*.class" ,
1889- output_name_a , * program_id , * program_id , package_dir );
1896+
1897+ for (program_id = program_id_list ; * program_id ; ++ program_id ) {
1898+ snprintf (buff , BUFF_SIZE ,
1899+ "cd %s && jar --create --main-class=%s --file=%s.jar "
1900+ "%s%c%s.class %s%c%s$*.class" ,
1901+ output_name_a , * program_id , * program_id , package_dir ,
1902+ file_path_delimitor , * program_id , package_dir ,
1903+ file_path_delimitor , * program_id );
18901904 ret = process (buff );
18911905 if (ret ) {
18921906 return ret ;
18931907 }
1894- snprintf (buff , COB_MEDIUM_BUFF , "%s %s%c%s.class %s%c%s$*.class" ,
1895- remove_cmd , output_name_a , file_path_delimitor , * program_id ,
1896- output_name_a , file_path_delimitor , * program_id );
1908+ #ifdef _WIN32
1909+ char remove_cmd [] = "del" ;
1910+ #else
1911+ char remove_cmd [] = "rm" ;
1912+ #endif
1913+ snprintf (buff , BUFF_SIZE , "%s %s%c%s%c%s.class %s%c%s%c%s$*.class" ,
1914+ remove_cmd , output_name_a , file_path_delimitor , package_dir ,
1915+ file_path_delimitor , * program_id , output_name_a ,
1916+ file_path_delimitor , package_dir , file_path_delimitor ,
1917+ * program_id );
18971918 process (buff );
18981919 }
18991920 }
1921+ #undef BUFF_SIZE
19001922 return ret ;
19011923}
19021924
1903- static int process_build_module ( struct filename * fn ) {
1925+ static int process_build_module_all ( void ) {
19041926 int ret = 0 ;
19051927 char buff [COB_MEDIUM_BUFF ];
1906- char name [COB_MEDIUM_BUFF ];
1907-
1908- char basename [COB_MEDIUM_BUFF ];
1909- file_basename (fn -> source , basename );
1910- struct cb_program * p ;
19111928#ifdef _WIN32
19121929 char remove_cmd [] = "del" ;
19131930#else
19141931 char remove_cmd [] = "rm" ;
19151932#endif
19161933
1917- if (output_name ) {
1918- strcpy (name , output_name );
1919- #if defined(_MSC_VER )
1920- file_stripext (name );
1921- #else
1922- if (strchr (output_name , '.' ) == NULL ) {
1923- strcat (name , "." );
1924- strcat (name , COB_MODULE_EXT );
1925- }
1926- #endif
1927- } else {
1928- file_basename (fn -> source , name );
1929- #if !defined(_MSC_VER )
1930- strcat (name , "." );
1931- strcat (name , COB_MODULE_EXT );
1932- #endif
1933- }
1934-
1935- for (p = current_program ; p ; p = p -> next_program ) {
1936- sprintf (buff , "jar cf %s.jar ./%s.class ./%s$*.class" , p -> program_id ,
1937- p -> program_id , p -> program_id );
1934+ char * * program_id ;
1935+ for (program_id = program_id_list ; * program_id ; ++ program_id ) {
1936+ sprintf (buff , "jar cf %s.jar ./%s.class ./%s$*.class" , * program_id ,
1937+ * program_id , * program_id );
19381938 ret = process (buff );
19391939 if (ret ) {
19401940 return ret ;
19411941 }
1942- sprintf (buff , "%s %s.class %s$*.class" , remove_cmd , p -> program_id ,
1943- p -> program_id );
1942+ sprintf (buff , "%s %s.class %s$*.class" , remove_cmd , * program_id ,
1943+ * program_id );
19441944 ret = process (buff );
19451945 if (ret ) {
19461946 return ret ;
@@ -2374,6 +2374,13 @@ int main(int argc, char *argv[]) {
23742374 cb_pretty_display = 0 ;
23752375 }
23762376
2377+ /* Check if the number of COBOL programs exceeds the limit */
2378+ if (argc - iargs > PROGRAM_ID_LIST_MAX_LEN ) {
2379+ fprintf (stderr , "Error: Too many COBOL programs (max %d)\n" ,
2380+ PROGRAM_ID_LIST_MAX_LEN );
2381+ exit (1 );
2382+ }
2383+
23772384 while (iargs < argc ) {
23782385 fn = process_filename (argv [iargs ++ ]);
23792386 if (!fn ) {
@@ -2389,6 +2396,13 @@ int main(int argc, char *argv[]) {
23892396 }
23902397 }
23912398 }
2399+
2400+ /* Initialize program_id_list before translation loop */
2401+ program_id_list_index = 0 ;
2402+ for (int i = 0 ; i < PROGRAM_ID_LIST_MAX_LEN ; ++ i ) {
2403+ program_id_list [i ] = NULL ;
2404+ }
2405+
23922406 for (fn = file_list ; fn ; fn = fn -> next ) {
23932407 cb_id = 1 ;
23942408 cb_attr_id = 1 ;
@@ -2434,24 +2448,26 @@ int main(int argc, char *argv[]) {
24342448 continue ;
24352449 }
24362450
2437- /* Compile */
2438- if (!cb_single_jar_name && (cb_compile_level == CB_LEVEL_COMPILE ||
2439- cb_compile_level == CB_LEVEL_MODULE )) {
2440- if (process_compile (fn ) != 0 ) {
2441- cobc_clean_up (status );
2442- return status ;
2443- }
2451+ /* Build executable */
2452+ if (cb_compile_level == CB_LEVEL_EXECUTABLE ) {
2453+ fprintf (stderr , "Building executable files is not supported" );
24442454 }
2455+ }
24452456
2446- /* Build module */
2447- if (cb_compile_level == CB_LEVEL_MODULE ) {
2448- if (process_build_module (fn ) != 0 ) {
2449- cobc_clean_up (status );
2450- return status ;
2451- }
2452- /* Build executable */
2453- } else if (cb_compile_level == CB_LEVEL_EXECUTABLE ) {
2454- fprintf (stderr , "Building executable files is not supported" );
2457+ /* Compile all Java files at once after all translations are complete */
2458+ if (!cb_single_jar_name && (cb_compile_level == CB_LEVEL_COMPILE ||
2459+ cb_compile_level == CB_LEVEL_MODULE )) {
2460+ if (process_compile_all () != 0 ) {
2461+ cobc_clean_up (status );
2462+ return status ;
2463+ }
2464+ }
2465+
2466+ /* Build module for all programs */
2467+ if (cb_compile_level == CB_LEVEL_MODULE ) {
2468+ if (process_build_module_all () != 0 ) {
2469+ cobc_clean_up (status );
2470+ return status ;
24552471 }
24562472 }
24572473
0 commit comments