Noble Ape
The Central Directories of the Noble Ape Simulation.
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros
io.c
Go to the documentation of this file.
1 /****************************************************************
2 
3  io.c
4 
5  =============================================================
6 
7  Copyright 1996-2014 Tom Barbalet. All rights reserved.
8 
9  Permission is hereby granted, free of charge, to any person
10  obtaining a copy of this software and associated documentation
11  files (the "Software"), to deal in the Software without
12  restriction, including without limitation the rights to use,
13  copy, modify, merge, publish, distribute, sublicense, and/or
14  sell copies of the Software, and to permit persons to whom the
15  Software is furnished to do so, subject to the following
16  conditions:
17 
18  The above copyright notice and this permission notice shall be
19  included in all copies or substantial portions of the Software.
20 
21  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
23  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
25  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
26  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
28  OTHER DEALINGS IN THE SOFTWARE.
29 
30  This software and Noble Ape are a continuing work of Tom Barbalet,
31  begun on 13 June 1996. No apes or cats were harmed in the writing
32  of this software.
33 
34  ****************************************************************/
35 
42 #include "noble.h"
43 #include <string.h>
44 #include <stdlib.h>
45 #include <stdio.h>
46 
47 static n_int command_line_execution;
48 static n_int command_line_external_exit = 0;
49 
50 #define CHAR_TAB (9)
51 #define CHAR_SPACE (32)
52 
53 /* this is v2 of the file parsing, v3 is soon to be implemented through the scripting interface */
54 #define CHAR_EOF 0
55 #define IS_RETURN(val) (((val) == 10) || ((val) == 13))
56 #define IS_TAB(val) ((val) == CHAR_TAB)
57 #define IS_SPACE(val) ((val) == CHAR_SPACE)
58 #define IS_WHITE_HORIZON(val) (IS_TAB(val) || IS_SPACE(val))
59 #define IS_WHITE_SPACE(val) (IS_WHITE_HORIZON((val))||IS_RETURN((val)))
60 #define FILE_END_INCLUSION 0x0101
61 #define FILE_TYPE(num) ((num)&0x07)
62 #define FILE_CONTINUATION 0x80
63 
65 {
66  command_line_execution = 1;
67 }
68 
70 {
71  return command_line_execution;
72 }
73 
74 void io_entry_execution(n_int argc, n_string * argv)
75 {
76  if (argv)
77  {
78  if ((argc == 2) && (argv[1][0] == 'c'))
79  {
81  }
82  }
83 }
84 
91 void io_copy(n_byte * from, n_byte * to, n_uint number)
92 {
93  memcpy(to, from, number);
94 }
95 
101 void * io_new(n_uint bytes)
102 {
103  void * tmp = 0L;
104  if (bytes)
105  {
106  tmp = (void *) malloc(bytes);
107  }
108  return (tmp);
109 }
110 
115 void io_free(void ** ptr)
116 {
117  if (*ptr != 0L)
118  {
119  free(*ptr);
120  *ptr = 0L;
121  }
122 }
123 
130 void * io_new_range(n_uint memory_min, n_uint *memory_allocated)
131 {
132  void * memory_buffer = 0L;
133  do
134  {
135  memory_buffer = (void *) malloc(*memory_allocated);
136  if (memory_buffer == 0L)
137  {
138  *memory_allocated = ((*memory_allocated) * 3) >> 2;
139  }
140  }
141  while((memory_buffer == 0L) && ((*memory_allocated)>memory_min));
142  return memory_buffer;
143 }
144 
151 void io_lower(n_string value, n_int length)
152 {
153  n_int loop = 0;
154  while (loop < length)
155  {
156  IO_LOWER_CHAR(value[loop]);
157  loop++;
158  }
159 }
160 
166 {
167  n_file * output = io_new(sizeof(n_file));
168  if (output == 0L)
169  {
170  return 0L;
171  }
172  output->size = 4096;
173  output->data = io_new(4096);
174  if (output->data == 0L)
175  {
176  io_free((void **)&output);
177  return 0L;
178  }
179  output->location = 0;
180  return output;
181 }
182 
183 
188 void io_file_free(n_file ** file)
189 {
190  if (file != 0L)
191  {
192  io_free((void **)&((*file)->data));
193  }
194  io_free((void **)file);
195 }
196 
197 void io_int_to_bytes(n_int value, n_byte * bytes)
198 {
199  io_copy((n_byte *)&value, bytes, sizeof(n_int));
200 }
201 
203 {
204  /*n_uint unsigned_value;*/
205  n_int return_value;
206 
207  io_copy(bytes, (n_byte *)&return_value, sizeof(n_int));
208  return return_value;
209 }
210 
217 n_int io_disk_read(n_file * local_file, n_string file_name)
218 {
219 #ifndef _WIN32
220  FILE * in_file = fopen(file_name,"rb");
221 #else
222  FILE * in_file = 0L;
223  fopen_s(&in_file,file_name,"rb");
224 #endif
225  if (in_file == 0L)
226  {
227  return SHOW_ERROR("File does not exist");
228  }
229  while (!feof(in_file))
230  {
231  n_byte local_char;
232  if (fread(&local_char,1,1,in_file)>0)
233  {
234  if (!feof(in_file))
235  {
236  n_int error = io_file_write(local_file, local_char);
237  if (error != 0)
238  {
239  return FILE_ERROR;
240  }
241  }
242  }
243  }
244  fclose(in_file);
245  return FILE_OKAY;
246 }
247 
254 n_int io_disk_write(n_file * local_file, n_string file_name)
255 {
256  n_uint written_length;
257  FILE * out_file = 0L;
258 #ifndef _WIN32
259  out_file = fopen(file_name,"wb");
260 #else
261  fopen_s(&out_file,file_name,"wb");
262 #endif
263  if (out_file == 0L)
264  {
265  return SHOW_ERROR("Error opening file to write");
266  }
267  if (local_file->data == 0L)
268  {
269  return SHOW_ERROR("No data in file to be written");
270  }
271 
272  written_length = fwrite(local_file->data,1,local_file->location, out_file);
273 
274  if (fclose(out_file) != 0)
275  {
276  return SHOW_ERROR("File could not be closed");
277  }
278 
279  if (written_length != local_file->location)
280  {
281  return SHOW_ERROR("File did not complete write");
282  }
283  return FILE_OKAY;
284 }
285 
293 {
294 #ifndef _WIN32
295  FILE * local_check_file = fopen(file_name,"rb");
296 #else
297  FILE * local_check_file = 0L;
298 
299  fopen_s(&local_check_file,file_name,"rb");
300 #endif
301 
302  if (local_check_file == 0L)
303  return 0;
304 
305  if (fclose(local_check_file) != 0)
306  {
307  return 0;
308  }
309  return 1;
310 }
311 
318 n_int io_read_bin(n_file * fil, n_byte * local_byte)
319 {
320  n_uint file_location = fil -> location;
321  if (file_location >= (fil -> size))
322  {
323  return -1;
324  }
325 
326  *local_byte = fil -> data[file_location];
327  fil->location = (file_location + 1);
328  return 0;
329 }
330 
336 static n_byte io_read(n_file * fil)
337 {
338  n_byte val = 0;
339  if (io_read_bin(fil, &val) == -1)
340  {
341  return(CHAR_EOF);
342  }
343  return (val);
344 }
345 
353 n_string * io_tab_delimit_to_n_string_ptr(n_file * tab_file, n_int * size_value, n_int * row_value)
354 {
355  n_int string_point_location = 1;
356  n_int first_value = 0;
357  n_uint loop = 0;
358  n_string *string_point;
359  n_int local_row_value = 0;
360  n_byte resultant_value;
361 
362  if (tab_file->location != 0)
363  {
364  while (loop < tab_file->location)
365  {
366  resultant_value = tab_file->data[loop];
367  if (IS_TAB(resultant_value) || IS_RETURN(resultant_value))
368  {
369  tab_file->data[loop] = 0;
370  first_value = 1;
371  if ((local_row_value == 0) && IS_RETURN(resultant_value))
372  {
373  local_row_value = string_point_location;
374  }
375  }
376  else
377  {
378  if (first_value)
379  {
380  string_point_location++;
381  first_value = 0;
382  }
383  }
384  loop ++;
385  }
386  }
387 
388  if (size_value != 0L)
389  {
390  *size_value = string_point_location;
391  }
392 
393  if (row_value != 0L)
394  {
395  *row_value = local_row_value;
396  }
397 
398  if (tab_file->location == 0)
399  {
400  return 0L;
401  }
402 
403  if ((string_point = (n_string *)io_new(string_point_location*sizeof(n_string *))) == 0L)
404  {
405  return 0L;
406  }
407 
408  string_point_location = 0;
409  first_value = 0;
410  loop = 0;
411 
412  string_point[string_point_location++] = (n_string)&(tab_file->data[0]);
413  while (loop < tab_file->location)
414  {
415  resultant_value = tab_file->data[loop];
416  if ((first_value) && (resultant_value != 0))
417  {
418  string_point[string_point_location++] = (n_string)&(tab_file->data[loop]);
419  first_value = 0;
420  }
421  if (resultant_value == 0)
422  {
423  first_value = 1;
424  }
425  loop ++;
426  }
427 
428  return string_point;
429 }
430 
438 n_int io_read_byte4(n_file * fil, n_uint * actual_value, n_byte * final_char)
439 {
440  n_uint temp = 0;
441  n_int ten_power_place = 0;
442  while (1)
443  {
444  n_byte value = io_read(fil);
445  n_uint mod_ten;
446  if (!ASCII_NUMBER(value))
447  {
448  *actual_value = temp;
449  *final_char = value;
450  return ten_power_place;
451  }
452  mod_ten = value - '0';
453  if ((temp == 429496729) && (mod_ten > 5))
454  {
455  return -1;
456  }
457  if (temp > 429496729)
458  {
459  return -1;
460  }
461  temp = (temp * 10) + mod_ten;
462  ten_power_place++;
463  }
464 }
465 
473 n_int io_number(n_string number_string, n_int * actual_value, n_int * decimal_divisor)
474 {
475  n_uint temp = 0;
476  n_int divisor = 0;
477  n_int ten_power_place = 0;
478  n_int string_point = 0;
479  n_byte negative = 0;
480 
481  if (number_string == 0L) return -1;
482  if (number_string[0] == 0) return -1;
483 
484  if (number_string[0] == '-')
485  {
486  negative = 1;
487  string_point++;
488  }
489 
490  while (1)
491  {
492  n_byte value = number_string[string_point++];
493  n_uint mod_ten;
494  if (value == 0)
495  {
496  n_int translate;
497 
498  if (negative == 1)
499  {
500  translate = 0 - temp;
501  }
502  else
503  {
504  translate = temp;
505  }
506 
507  *actual_value = translate;
508 
509  if (divisor > 0)
510  {
511  divisor--;
512  }
513 
514  *decimal_divisor = divisor;
515  return ten_power_place;
516  }
517  if (value == '.')
518  {
519  if (divisor != 0)
520  {
521  return -1;
522  }
523  divisor = 1;
524  }
525  else
526  {
527  if (!ASCII_NUMBER(value))
528  {
529  return -1;
530  }
531 
532  mod_ten = value - '0';
533  if (temp == 214748364)
534  {
535  if (negative == 1)
536  {
537  if (mod_ten > 8)
538  {
539  return -1;
540  }
541  }
542  else
543  {
544  if (mod_ten > 7)
545  {
546  return -1;
547  }
548  }
549  }
550  if (temp > 214748364)
551  {
552  return -1;
553  }
554  if (divisor != 0)
555  {
556  divisor++;
557  }
558  temp = (temp * 10) + mod_ten;
559  ten_power_place++;
560  }
561  }
562 }
563 
564 #define ASCII_WHITESPACE(num) ((((num)>8)&&((num)<14))||((num)==32))
565 
570 void io_whitespace(n_file * input)
571 {
572  n_uint loop = 0, out_loop = 0;
573  n_uint end_loop = input->size;
574  n_byte *local_data = input->data;
575  while(loop<end_loop)
576  {
577  n_byte temp = local_data[loop++];
578 
579  if((temp == '/') && (loop != end_loop))
580  {
581  n_byte check_twice[2]= {'/', 0};
582  check_twice[1] = local_data[loop++];
583  if(check_twice[1] != '*')
584  {
585  local_data[out_loop++] = '/';
586  if(ASCII_WHITESPACE(check_twice[1]) == 0)
587  {
588  local_data[out_loop++] = check_twice[1];
589  }
590  }
591  else
592  {
593  check_twice[0] = 0;
594  check_twice[1] = 0;
595  do
596  {
597  check_twice[0] = check_twice[1];
598  check_twice[1] = local_data[loop++];
599  }
600  while((loop != end_loop) && !((check_twice[0]=='*')&&(check_twice[1]=='/')));
601  }
602  }
603  else if(ASCII_WHITESPACE(temp) == 0)
604  {
605  local_data[out_loop++] = temp;
606  }
607  }
608  loop = out_loop;
609  while (loop < end_loop)
610  {
611  local_data[loop++] = 0;
612  }
613  input->size = out_loop;
614 
615 }
616 
626 {
627  n_uint local_size = fil->size;
628  if((fil->location + 1) == local_size)
629  {
630  /* This logic had to be changed for large file handling.*/
631  n_uint temp_size;
632  n_byte *temp_data;
633  if (local_size <= (256*1024))
634  {
635  temp_size = local_size * 4;
636  }
637  else
638  {
639  if (local_size <= (512*1024*1024))
640  {
641  temp_size = local_size * 2;
642  }
643  else
644  {
645  temp_size = (local_size * 3) >> 1;
646  }
647  }
648  temp_data = io_new(temp_size);
649  if (temp_data == 0L)
650  {
651  return(SHOW_ERROR("Attempted file overwrite"));
652  }
653  io_copy(fil->data, temp_data, local_size);
654  io_free((void **)&(fil->data));
655  fil->data = temp_data;
656  fil->size = temp_size;
657  }
658  fil->data[fil->location++] = byte;
659  return (FILE_OKAY);
660 }
661 
662 /* Memory saving */
664 {
665  io_erase(fil->data, fil->size);
666  fil->location = 0;
667 }
668 
669 /*
670  This is too slow, consider:
671 
672  n_uint io_length(n_string s) {
673  n_string start = s;
674  while(*s)s++;
675  return s - start;
676  }
677 */
678 
679 /* this is used for finding the actual length of fixed length strings, max length is enforced */
681 {
682  n_int return_length = -1;
683  if (max < 1)
684  {
685  return -1;
686  }
687  do
688  {
689  return_length++;
690  }
691  while ((value[return_length] != 0) && (return_length < max));
692  return return_length;
693 }
694 
695 /*
696 
697  These are too slow too.
698 
699  Consider:
700 
701 return <0 if s<t, 0 if s==t, >0 if s>t
702 
703 
704 n_int io_find(n_string s, n_string t)
705 {
706  for ( ; *s == *t; s++, t++)
707  if (*s == '\0')
708  return 0;
709  return *s - *t;
710 }
711 
712  */
713 
714 n_int io_find(n_string check, n_int from, n_int max, n_string value_find, n_int value_find_length)
715 {
716  n_int loop = from;
717  n_int check_length = 0;
718  while (loop < max)
719  {
720  if (check[loop] == value_find[check_length])
721  {
722  check_length++;
723  if (check_length == value_find_length)
724  {
725  return loop + 1;
726  }
727  }
728  else
729  {
730  check_length = 0;
731  }
732  loop ++;
733  }
734  return -1;
735 }
736 
737 /* writes a string, adding a new line if required in the OS correct format */
738 #define FILE_MACRO_WRITE(ch) if(io_file_write(fil,(ch)) == -1) return -1
739 
741 {
742  if (ch[0] != 0)
743  {
744  n_uint lp = 0;
745  while (ch[lp] != 0)
746  {
747  FILE_MACRO_WRITE(ch[lp++]);
748  }
749  }
750  if (new_line&1)
751  {
752 #ifndef _WIN32
753  FILE_MACRO_WRITE(10);
754 #else
755  FILE_MACRO_WRITE(13);
756  FILE_MACRO_WRITE(10);
757 #endif
758  }
759  if (new_line&2)
760  {
761  FILE_MACRO_WRITE(9);
762  }
763  return (FILE_OKAY);
764 }
765 
766 /* writes a 16-bit or 8-bit number with an end terminator(,/;) and new line if required */
767 /* n_int error */
768 n_int io_writenumber(n_file * fil, n_int loc_val, n_uint numer, n_uint denom)
769 {
770  n_byte number_buffer[14] = {0};
771  n_byte negative;
772  n_byte decimal = 0;
773  n_uint positive_number;
774  n_int location = 12;
775  if(loc_val < 0)
776  {
777  negative = 1;
778  positive_number = 0 - loc_val;
779  }
780  else
781  {
782  negative = 0;
783  positive_number = loc_val;
784  }
785 
786  if(denom != 0)
787  {
788  n_uint roll_over = positive_number;
789 
790  positive_number = positive_number * numer * 100;
791 
792  if(positive_number < roll_over)
793  return -1;
794 
795  positive_number = positive_number / denom;
796  decimal = 1;
797  }
798 
799  do
800  {
801  number_buffer[location --] = (n_byte)((positive_number % 10) + '0');
802  positive_number = positive_number / 10;
803  if(decimal && location == 10)
804  {
805  number_buffer[location --] = '.';
806  if(positive_number == 0)
807  number_buffer[location --] = '0';
808  }
809  }
810  while((positive_number>0) || (decimal && (location > 9)));
811  if(negative)
812  number_buffer[location] = '-';
813  else
814  location++;
815  return io_write(fil, (n_string)&number_buffer[location], 0);
816 }
817 
818 n_int io_writenum(n_file * fil, n_int loc_val, n_byte ekind, n_byte new_line)
819 {
820  n_int return_val = io_writenumber(fil, loc_val,1,0);
821  n_byte ekind_buffer[2] = {0};
822  if(return_val!=FILE_OKAY)
823  return return_val;
824  ekind_buffer[0] = ekind;
825 
826  return io_write(fil, (n_string)ekind_buffer, new_line);
827 }
828 
829 /* find the variable command */
830 n_int io_command(n_file * fil, const noble_file_entry * commands)
831 {
832  n_byte found_text[7] = {0};
833  n_byte * commands_bytes = (n_byte *) commands[0].characters;
834 
835  n_byte2 lp = 0;
836 
837  found_text[0] = io_read(fil);
838  if (found_text[0] == 0)
839  {
840  return (FILE_EOF);
841  }
842  found_text[1] = io_read(fil);
843  if (found_text[0] == '}' && found_text[1] == ';')
844  {
845  return (FILE_END_INCLUSION);
846  }
847  found_text[2] = io_read(fil);
848  found_text[3] = io_read(fil);
849  found_text[4] = io_read(fil);
850  found_text[5] = io_read(fil);
851 
852  while (POPULATED(commands_bytes))
853  {
854  commands_bytes = (n_byte *) commands[lp].characters;
855  if (((commands_bytes[0] == found_text[0]) && (commands_bytes[1] == found_text[1])) &&
856  ((commands_bytes[2] == found_text[2]) && (commands_bytes[3] == found_text[3])) &&
857  ((commands_bytes[4] == found_text[4]) && (commands_bytes[5] == found_text[5])))
858  {
859  return (lp);
860  }
861  lp ++;
862  }
863 
864  io_output_contents(fil);
865 
866  return SHOW_ERROR((n_constant_string)found_text);
867 }
868 
869 /* find the largest size data unit to handle the file copying to data structures */
871 {
872  n_uint max_entry = 0;
873  n_int lp = 1;
874  n_byte last_incl = FILE_INCL(commands[0].incl_kind);
875  n_byte *last_characters;
876  do{
877  n_byte data_incl = FILE_INCL(commands[lp].incl_kind);
878  last_characters = commands[lp].characters;
879  if (last_incl != data_incl)
880  {
881  n_uint local_kind = FILE_KIND(commands[lp-1].incl_kind);
882  n_uint data_size;
883  n_uint running_entry = commands[lp-1].start_location;
884 
885  switch(local_kind)
886  {
887  case FILE_TYPE_BYTE4:
888  data_size = 4;
889  break;
890  case FILE_TYPE_BYTE2:
891  data_size = 2;
892  break;
893  default:
894  data_size = 1;
895  break;
896  }
897 
898  running_entry += data_size * commands[lp-1].number_entries;
899  if (running_entry > max_entry)
900  {
901  max_entry = running_entry;
902  }
903  last_incl = data_incl;
904  }
905  lp++;
906  }
907  while (POPULATED(last_characters));
908  return max_entry;
909 }
910 
911 #define FILE_MACRO_CONCLUSION(ch) (((comman_req==1) && (ch) == ',') || \
912  ((comman_req==0) && (ch) == ';'))
913 
914 /* after the variable command, read the kind of data in specified through the commands array */
915 /* n_int error */
916 n_int io_read_data(n_file * fil, n_byte2 command, n_byte * data_read)
917 {
918  n_int comman_req = ((command & FILE_CONTINUATION) == FILE_CONTINUATION);
919  n_byte type_from_command = (n_byte)FILE_TYPE(command);
920 
921  if (type_from_command == FILE_TYPE_PACKED)
922  {
923  n_uint loop = 0;
924  n_byte buffer[5]= {0};
925  n_uint output_val;
926  n_byte num_char;
927 
928  if (data_read == 0L)
929  {
930  return (FILE_OKAY);
931  }
932 
933  while (loop < PACKED_DATA_BLOCK)
934  {
935  buffer[0] = io_read(fil);
936  buffer[1] = io_read(fil);
937  buffer[2] = io_read(fil);
938 
939  output_val = (buffer[0]-65);
940  output_val += (buffer[1]-65) * 41;
941  output_val += (buffer[2]-65) * 41 * 41;
942 
943  data_read[loop++] = (output_val >> 0) & 255;
944  data_read[loop++] = (output_val >> 8) & 255;
945  }
946  num_char = io_read(fil);
947 
948  if (FILE_MACRO_CONCLUSION(num_char))
949  return (FILE_OKAY);
950  return SHOW_ERROR("Packed ends incorrectly");
951  }
952 
953  if ((type_from_command == FILE_TYPE_BYTE) ||
954  (type_from_command == FILE_TYPE_BYTE_EXT) ||
955  (type_from_command == FILE_TYPE_BYTE2) ||
956  (type_from_command == FILE_TYPE_BYTE4))
957  {
958  n_uint number = 0;
959  n_byte num_char;
960  n_int response_code = io_read_byte4(fil, &number, &num_char);
961 
962  if (response_code == 0)
963  {
964  return SHOW_ERROR("Expected number not found");
965  }
966  if (response_code < 0)
967  {
968  return SHOW_ERROR("Expected number too big");
969  }
970 
971  if ((type_from_command == FILE_TYPE_BYTE) || (type_from_command == FILE_TYPE_BYTE_EXT))
972  {
973  if (number > 0x000000ff)
974  return SHOW_ERROR("Expected byte too big");
975  data_read[0] = (n_byte) number;
976  }
977 
978  if (type_from_command == FILE_TYPE_BYTE2)
979  {
980  n_byte2 * data_read2 = (n_byte2 *)data_read;
981  if (number > 0x0000ffff)
982  return SHOW_ERROR("Expected two byte too big");
983  data_read2[0] = (n_byte2) number;
984  }
985 
986  if (type_from_command == FILE_TYPE_BYTE4)
987  {
988  n_byte4 * data_read4 = (n_byte4 *)data_read;
989  data_read4[0] = (n_byte4) number;
990  }
991 
992  if (FILE_MACRO_CONCLUSION(num_char))
993  return (FILE_OKAY);
994  return SHOW_ERROR("Number ends incorrectly");
995  }
996  return SHOW_ERROR("Type not found");
997 }
998 
1000 {
1001  n_uint loop = 0;
1002  printf("--------------------FILE--------------------\n");
1003  printf("Location %ld\n", file->location);
1004  printf("Size %ld\n", file->size);
1005  printf("* * * * * * \n");
1006 
1007  while (loop < file->location)
1008  {
1009  printf("%c", file->data[loop++]);
1010  }
1011  printf("--------------------------------------------n");
1012 
1013 }
1014 
1025 n_int io_read_buff(n_file * fil, n_byte * data, const noble_file_entry * commands)
1026 {
1027 
1028  n_int inclusion_number = 0xffff;
1029  n_int result_number = 0;
1030  do
1031  {
1032  result_number = io_command(fil, commands);
1033  if(result_number == -1)
1034  return SHOW_ERROR("Unknown command");
1035 
1036  if (result_number > 0x00ff)
1037  {
1038  if (result_number != FILE_END_INCLUSION)
1039  return (result_number);
1040  }
1041  else
1042  {
1043  n_byte com_inclusion = FILE_INCL(commands[result_number].incl_kind);
1044  n_byte com_kind = FILE_KIND(commands[result_number].incl_kind);
1045 
1046  n_uint com_number_of = commands[result_number].number_entries;
1047  n_uint com_location = commands[result_number].start_location;
1048 
1049  n_uint loop = 0;
1050  n_byte *local_data = &data[com_location];
1051 
1052  if (inclusion_number == 0xffff)
1053  {
1054  if (commands[result_number].characters[5] != '{')
1055  return SHOW_ERROR("{ expected in the file");
1056  inclusion_number = com_inclusion;
1057  }
1058  if (inclusion_number != com_inclusion)
1059  return SHOW_ERROR("Wrong start in file");
1060 
1061  while (loop < com_number_of)
1062  {
1063  n_byte local_kind = com_kind;
1064  if ((loop + 1) != com_number_of)
1065  {
1066  local_kind |= FILE_CONTINUATION;
1067  }
1068  if (io_read_data(fil, local_kind, local_data) != FILE_OKAY)
1069  {
1070  return (FILE_ERROR);
1071  }
1072  if (com_kind == FILE_TYPE_PACKED)
1073  {
1074  local_data = &local_data[ PACKED_DATA_BLOCK ];
1075  }
1076  else
1077  {
1078  if (com_kind == FILE_TYPE_BYTE_EXT)
1079  {
1080  local_data = &local_data[ 1 ];
1081  }
1082  else
1083  {
1084  local_data = &local_data[ com_kind ];
1085  }
1086  }
1087  loop++;
1088  }
1089  }
1090  }
1091  while (result_number != FILE_END_INCLUSION);
1092  return (inclusion_number);
1093 }
1094 
1095 #define IO_CHECK_ERROR(cnd) \
1096  { \
1097  n_int out_cnd = cnd; \
1098  if ( (out_cnd) != FILE_OKAY) \
1099  return out_cnd; \
1100  }
1101 
1112 n_int io_write_buff(n_file * fil, void * data, const noble_file_entry * commands, n_byte command_num, n_file_specific * func)
1113 {
1114  if (command_num == FILE_COPYRIGHT)
1115  {
1116  n_string *fluff = (n_string *) data;
1117 
1118  IO_CHECK_ERROR(io_write(fil, "/*", 3));
1119  IO_CHECK_ERROR(io_write(fil, fluff[0], 0));
1120  IO_CHECK_ERROR(io_write(fil, fluff[1], 3));
1121 
1122  IO_CHECK_ERROR(io_write(fil, fluff[2], 0));
1123  IO_CHECK_ERROR(io_write(fil, fluff[3], 0));
1124  IO_CHECK_ERROR(io_write(fil, fluff[4], 1));
1125  IO_CHECK_ERROR(io_write(fil, "*/", 1));
1126  IO_CHECK_ERROR(io_write(fil, "", 1));
1127 
1128  return (FILE_OKAY);
1129  }
1130  {
1131  const n_byte *commands_bytes;
1132  n_byte writeout_commands[7]= {0};
1133  n_uint offset = 0;
1134  n_int release = FILE_ERROR;
1135  do
1136  {
1137  commands_bytes = commands[offset].characters;
1138  if ((commands_bytes[0] == 0) && (commands_bytes[1] == 0) &&
1139  (commands_bytes[2] == 0) && (commands_bytes[3] == 0) &&
1140  (commands_bytes[4] == 0) && (commands_bytes[5] == 0))
1141  {
1142  return SHOW_ERROR("File command not found");
1143  }
1144 
1145  if (FILE_INCL(commands[offset].incl_kind) == command_num)
1146  release = FILE_OKAY;
1147  else
1148  offset++;
1149  }
1150  while (release == FILE_ERROR);
1151  writeout_commands[0] = commands_bytes[0];
1152  writeout_commands[1] = commands_bytes[1];
1153  writeout_commands[2] = commands_bytes[2];
1154  writeout_commands[3] = commands_bytes[3];
1155  writeout_commands[4] = commands_bytes[4];
1156  writeout_commands[5] = commands_bytes[5];
1157 
1158  IO_CHECK_ERROR(io_write(fil, (n_string)writeout_commands, 3));
1159  release = FILE_ERROR;
1160  offset++;
1161  do
1162  {
1163  commands_bytes = commands[offset].characters;
1164 
1165  if ((commands_bytes[0] == 0) && (commands_bytes[1] == 0) &&
1166  (commands_bytes[2] == 0) && (commands_bytes[3] == 0) &&
1167  (commands_bytes[4] == 0) && (commands_bytes[5] == 0))
1168  release = FILE_OKAY;
1169 
1170  if (FILE_INCL(commands[offset].incl_kind) != command_num)
1171  release = FILE_OKAY;
1172 
1173  if (release == FILE_ERROR)
1174  {
1175  n_uint loop = 0;
1176  n_byte data_type = FILE_KIND(commands[offset].incl_kind);
1177  n_uint end_loop = commands[offset].number_entries;
1178  n_uint data_offset = commands[offset].start_location;
1179  n_int right_ending = (FILE_INCL(commands[offset+1].incl_kind) != command_num);
1180 
1181  right_ending |= ((commands[offset+1].characters[0] == 0) && (commands[offset+1].characters[1] == 0) &&
1182  (commands[offset+1].characters[2] == 0) && (commands[offset+1].characters[3] == 0) &&
1183  (commands[offset+1].characters[4] == 0) && (commands[offset+1].characters[5] == 0));
1184  right_ending = 3 - (right_ending * 2);
1185 #if 0
1186  if (data_type == FILE_TYPE_PACKED)
1187  {
1188  if (unpack_data != 0L)
1189  {
1190  n_byte buffer[6]= {0};
1191  n_uint output_val;
1192  n_byte *local_unpack_data = unpack_data;
1193  writeout_commands[0] = commands_bytes[0];
1194  writeout_commands[1] = commands_bytes[1];
1195  writeout_commands[2] = commands_bytes[2];
1196  writeout_commands[3] = commands_bytes[3];
1197  writeout_commands[4] = commands_bytes[4];
1198  writeout_commands[5] = commands_bytes[5];
1199  IO_CHECK_ERROR(io_write(fil, (n_string)writeout_commands, (n_byte)right_ending));
1200  while (loop < end_loop)
1201  {
1202  n_uint data_loop = 0;
1203  while (data_loop < PACKED_DATA_BLOCK)
1204  {
1205  output_val = local_unpack_data[data_loop++];
1206  output_val |= local_unpack_data[data_loop++] << 8;
1207  buffer[0] = (output_val % 41) + 65;
1208  output_val /= 41;
1209  buffer[1] = (output_val % 41) + 65;
1210  output_val /= 41;
1211  buffer[2] = (output_val % 41) + 65;
1212 
1213  if ((data_loop % 80 ) == 0)
1214  {
1215  IO_CHECK_ERROR(io_write(fil, (n_string) buffer, (n_byte)right_ending));
1216  }
1217  else
1218  {
1219  IO_CHECK_ERROR(io_write(fil, (n_string) buffer, 0));
1220  }
1221  }
1222  local_unpack_data = &local_unpack_data[PACKED_DATA_BLOCK];
1223  loop++;
1224  if (loop == end_loop)
1225  {
1226  IO_CHECK_ERROR(io_write(fil, ";", (n_byte)right_ending));
1227  }
1228  else
1229  {
1230  IO_CHECK_ERROR(io_write(fil, ",", (n_byte)right_ending));
1231  }
1232  }
1233  }
1234  }
1235  else
1236 #endif
1237  {
1238  n_byte *byte_data = (n_byte *)data;
1239  if (data_type == FILE_TYPE_BYTE_EXT)
1240  {
1241  n_string_block block_code= {0};
1242  if (func != 0) (*func)((n_string)block_code, byte_data);
1243  IO_CHECK_ERROR(io_write(fil, "", 1));
1244  IO_CHECK_ERROR(io_write(fil, "", 2));
1245  IO_CHECK_ERROR(io_write(fil, "/* ", 0));
1246 
1247  IO_CHECK_ERROR(io_writenumber(fil, loop, 1, 0));
1248  IO_CHECK_ERROR(io_write(fil, "", 2));
1249  IO_CHECK_ERROR(io_write(fil, block_code, 0));
1250  IO_CHECK_ERROR(io_write(fil, " */", 2));
1251  }
1252 
1253  writeout_commands[0] = commands_bytes[0];
1254  writeout_commands[1] = commands_bytes[1];
1255  writeout_commands[2] = commands_bytes[2];
1256  writeout_commands[3] = commands_bytes[3];
1257  writeout_commands[4] = commands_bytes[4];
1258  writeout_commands[5] = commands_bytes[5];
1259 
1260  IO_CHECK_ERROR(io_write(fil, (n_string)writeout_commands, 0));
1261  while (loop < end_loop)
1262  {
1263  n_byte4 num_write = 0;
1264  switch (data_type)
1265  {
1266  case FILE_TYPE_BYTE_EXT:
1267  if((loop != 0) && ((loop % 3) == 0) && (loop != 126))
1268  {
1269  n_string_block block_code = {0};
1270  if (func != 0L) (*func)(block_code, &byte_data[data_offset + loop]);
1271  IO_CHECK_ERROR(io_write(fil, "", 1));
1272  IO_CHECK_ERROR(io_write(fil, "", 2));
1273  IO_CHECK_ERROR(io_write(fil, "/* ", 0));
1274  IO_CHECK_ERROR(io_writenumber(fil, loop, 1, 0));
1275  IO_CHECK_ERROR(io_write(fil, "", 2));
1276  IO_CHECK_ERROR(io_write(fil, (n_string)block_code, 0));
1277  IO_CHECK_ERROR(io_write(fil, " */", 2));
1278  }
1279  case FILE_TYPE_BYTE:
1280  num_write = byte_data[data_offset + loop];
1281  break;
1282  case FILE_TYPE_BYTE2:
1283  {
1284  num_write = ((n_byte2 *) &byte_data[data_offset + (loop * 2)])[0];
1285  }
1286  break;
1287  case FILE_TYPE_BYTE4:
1288  num_write = ((n_byte4 *) &byte_data[data_offset + (loop * 4)])[0];
1289  break;
1290  }
1291  loop++;
1292 
1293  if (loop == end_loop)
1294  {
1295  IO_CHECK_ERROR(io_writenum(fil, num_write, ';', (n_byte)right_ending));
1296  }
1297  else
1298  {
1299  IO_CHECK_ERROR(io_writenum(fil, num_write, ',', 0));
1300  }
1301  }
1302 
1303  }
1304  offset++;
1305  }
1306  }
1307  while (release == FILE_ERROR);
1308  IO_CHECK_ERROR(io_write(fil, "};", 1));
1309  IO_CHECK_ERROR(io_write(fil, "", 1));
1310  }
1311  return (FILE_OKAY);
1312 }
1313 
1314 /* write the output data with the commands array and the required copyright "fluff" */
1315 /* n_int error */
1316 n_int io_write_csv(n_file * fil, n_byte * data, const noble_file_entry * commands, n_byte command_num, n_byte initial)
1317 {
1318  if (command_num == FILE_COPYRIGHT)
1319  {
1320  return (FILE_OKAY);
1321  }
1322  {
1323  const n_byte * commands_bytes;
1324  n_uint offset = 0;
1325  n_int release = FILE_ERROR;
1326  n_byte first_entry = 1;
1327  n_byte writeout_commands[6]= {0};
1328  do
1329  {
1330  commands_bytes = commands[offset].characters;
1331  if ((commands_bytes[0] == 0) && (commands_bytes[1] == 0) &&
1332  (commands_bytes[2] == 0) && (commands_bytes[3] == 0) &&
1333  (commands_bytes[4] == 0) && (commands_bytes[5] == 0))
1334  return SHOW_ERROR("File command not found");
1335  if (FILE_INCL(commands[offset].incl_kind) == command_num)
1336  release = FILE_OKAY;
1337  else
1338  offset++;
1339  }
1340  while (release == FILE_ERROR);
1341 
1342  release = FILE_ERROR;
1343  offset++;
1344  do
1345  {
1346  commands_bytes = commands[offset].characters;
1347  if ((commands_bytes[0] == 0) && (commands_bytes[1] == 0) &&
1348  (commands_bytes[2] == 0) && (commands_bytes[3] == 0) &&
1349  (commands_bytes[4] == 0) && (commands_bytes[5] == 0))
1350  release = FILE_OKAY;
1351  if (FILE_INCL(commands[offset].incl_kind) != command_num)
1352  release = FILE_OKAY;
1353  if (release == FILE_ERROR)
1354  {
1355  n_uint loop = 0;
1356  n_byte data_type = FILE_KIND(commands[offset].incl_kind);
1357  n_uint end_loop = commands[offset].number_entries;
1358  n_uint data_offset = commands[offset].start_location;
1359 
1360  if (data_type != FILE_TYPE_PACKED)
1361  {
1362  while (loop < end_loop)
1363  {
1364  n_byte2 num_write = 0;
1365 
1366  if (first_entry == 0)
1367  {
1368  IO_CHECK_ERROR(io_write(fil, ",", 0));
1369  }
1370  else
1371  {
1372  first_entry = 0;
1373  }
1374 
1375  if (initial == 1)
1376  {
1377  writeout_commands[0] = commands_bytes[0];
1378  writeout_commands[1] = commands_bytes[1];
1379  writeout_commands[2] = commands_bytes[2];
1380  writeout_commands[3] = commands_bytes[3];
1381  writeout_commands[4] = commands_bytes[4];
1382  writeout_commands[5] = commands_bytes[5];
1383 
1384  IO_CHECK_ERROR(io_write(fil, (n_string)writeout_commands, 0));
1385  IO_CHECK_ERROR(io_writenumber(fil, loop, 1, 0));
1386  }
1387  else
1388  {
1389  switch (data_type)
1390  {
1391  case FILE_TYPE_BYTE:
1392  case FILE_TYPE_BYTE_EXT:
1393  num_write = data[data_offset + loop];
1394  break;
1395  case FILE_TYPE_BYTE2:
1396  num_write = ((n_byte2 *) & data[data_offset + (loop * 2)])[0];
1397  break;
1398  }
1399  IO_CHECK_ERROR(io_writenumber(fil, num_write, 1, 0));
1400  }
1401  loop++;
1402  }
1403  }
1404  offset++;
1405  }
1406  }
1407  while (release == FILE_ERROR);
1408  IO_CHECK_ERROR(io_write(fil, "", 1));
1409  }
1410  return (FILE_OKAY);
1411 }
1412 
1413 void io_erase(n_byte * buf_offscr, n_uint nestop)
1414 {
1415  memset(buf_offscr, 0, nestop);
1416 }
1417 
1418 void io_search_file_format(const noble_file_entry * format, n_string compare)
1419 {
1420  n_int loop = 0;
1421  n_byte print_file_format_exit = 0;
1422  n_byte print_file_place_show_all = 0;
1423  noble_file_entry * place;
1424  if (compare == 0L)
1425  {
1426  print_file_place_show_all = 2;
1427  }
1428  else
1429  {
1430  n_byte leave_condition = 0;
1431  do
1432  {
1433  place = (noble_file_entry *)&format[loop++];
1434  if ((place->characters[0] != 0) && (place->characters[1] != 0) &&
1435  (place->characters[2] != 0) && (place->characters[3] != 0) &&
1436  (place->characters[4] != 0) && (place->characters[5] != 0))
1437  {
1438  if ((place->characters[0] == compare[0]) && (place->characters[1] == compare[1]) &&
1439  (place->characters[2] == compare[2]) && (place->characters[3] == compare[3]) &&
1440  (place->characters[4] == compare[4]) && (0 == compare[5]))
1441  {
1442  leave_condition = 1;
1443  }
1444 
1445  }
1446  else
1447  {
1448  print_file_format_exit = 1;
1449  }
1450  }
1451  while((print_file_format_exit == 0) && (leave_condition == 0));
1452 
1453  if (print_file_format_exit == 1)
1454  {
1455  (void)SHOW_ERROR("String not found");
1456  return;
1457  }
1458  if(place->characters[5] =='{')
1459  {
1460  print_file_place_show_all = 1;
1461  }
1462  loop--;
1463  }
1464  do
1465  {
1466  place = (noble_file_entry *)&format[loop++];
1467  if ((place->characters[0] != 0) && (place->characters[1] != 0) &&
1468  (place->characters[2] != 0) && (place->characters[3] != 0) &&
1469  (place->characters[4] != 0) && (place->characters[5] != 0))
1470  {
1471  if (place->characters[5] == '{')
1472  {
1473  printf(" %c%c%c%c%c %s\n", place->characters[0],place->characters[1],place->characters[2],
1474  place->characters[3],place->characters[4], place->what_is_it);
1475  }
1476  else
1477  {
1478  printf(" %c%c%c%c%c %s\n", place->characters[0],place->characters[1],place->characters[2],
1479  place->characters[3],place->characters[4], place->what_is_it);
1480  }
1481 
1482  if (print_file_place_show_all == 0)
1483  {
1484  return;
1485  }
1486  if ((format[loop].characters[5]=='{') && (print_file_place_show_all == 1))
1487  {
1488  return;
1489  }
1490  }
1491  else
1492  {
1493  print_file_format_exit = 1;
1494  }
1495  }
1496  while(print_file_format_exit == 0);
1497 }
1498 
1499 void io_audit_file(const noble_file_entry * format, n_byte section_to_audit)
1500 {
1501  n_uint loop = 0;
1502  n_uint being_counter = 0;
1503  n_byte *local_characters;
1504  do
1505  {
1506  n_byte local_incl_kind = format[loop].incl_kind;
1507  n_uint local_number = format[loop].number_entries;
1508  n_uint local_location = format[loop].start_location;
1509  n_string_block printout_characters = {0};
1510  local_characters = (n_byte*)format[loop].characters;
1511  if ((local_incl_kind & 0xF0) == section_to_audit)
1512  {
1513  n_uint local_type = local_incl_kind & 0x0F;
1514 
1515  if (local_type == FILE_TYPE_BYTE_EXT)
1516  {
1517  local_type = FILE_TYPE_BYTE;
1518  }
1519 
1520  if ((local_type == FILE_TYPE_BYTE) || (local_type == FILE_TYPE_BYTE2) || (local_type == FILE_TYPE_BYTE4))
1521  {
1522  printout_characters[0] = local_characters[0];
1523  printout_characters[1] = local_characters[1];
1524  printout_characters[2] = local_characters[2];
1525  printout_characters[3] = local_characters[3];
1526  printout_characters[4] = local_characters[4];
1527  printout_characters[5] = local_characters[5];
1528 
1529  printf("%s \t %lu * %lu = %lu bytes \t reported/actual/diff offset %d / %d / %d\n", printout_characters,
1530  local_number, local_type, (local_number * local_type), (int)local_location, (int)being_counter, ((int)local_location - (int)being_counter));
1531 
1532  being_counter += (local_number * local_type);
1533  }
1534  }
1535  loop++;
1536  }
1537  while((local_characters[0] != 0) && (local_characters[1] != 0) &&
1538  (local_characters[2] != 0) && (local_characters[3] != 0));
1539 }
1540 
1542 
1543 
1544 void io_three_string_combination(n_string output, n_string first, n_string second, n_string third, n_int count)
1545 {
1546  n_int command_length = io_length(first, STRING_BLOCK_SIZE);
1547  n_int addition_length = io_length(second, STRING_BLOCK_SIZE);
1548  n_int total = count - (command_length + addition_length + 1);
1549  n_int loop2 = 0;
1550  n_int position = 0;
1551 
1552  io_string_write(output, " ", &position);
1553  io_string_write(output, first, &position);
1554  io_string_write(output, " ", &position);
1555  io_string_write(output, second, &position);
1556  while (loop2 < total)
1557  {
1558  io_string_write(output, " ", &position);
1559  loop2++;
1560 
1561  }
1562  io_string_write(output, third, &position);
1563 }
1564 
1565 void io_time_to_string(n_string value, n_int minutes, n_int days)
1566 {
1567  n_int military_time = (minutes % 60);
1568  n_int hours = (minutes/60);
1569  military_time += hours * 100;
1570  sprintf(value,"%4ld:%ld", military_time, days);
1571 }
1572 
1573 void io_offset(n_byte * start, n_byte * point, n_string text)
1574 {
1575  printf("%s %ld\n", text, (n_int)(point - start));
1576 }
1577 
1578 void io_help_line(noble_console_command * specific, n_console_output output_function)
1579 {
1580  n_string_block string_line = {0};
1581  io_three_string_combination(string_line, specific->command, specific->addition, specific->help_information, 28);
1582  output_function(string_line);
1583 }
1584 
1585 n_int io_help(void * ptr, n_string response, n_console_output output_function)
1586 {
1587  n_int loop = 0;
1588  n_int response_len = 0;
1589  n_int found = 0;
1590 
1591  if (response != 0L)
1592  {
1593  response_len = io_length(response, 1024);
1594  }
1595 
1596  if (response_len == 0)
1597  {
1598  output_function("Commands:");
1599  }
1600 
1601  do
1602  {
1603  if (local_commands[loop].function != 0L)
1604  {
1605  if ((local_commands[loop].help_information) && (local_commands[loop].help_information[0] != 0))
1606  {
1607  if (response_len == 0)
1608  {
1609  io_help_line(&local_commands[loop], output_function);
1610  }
1611  else
1612  {
1613  n_int command_len = io_length(local_commands[loop].command, 1024);
1614  n_int count = io_find(response, 0, response_len, local_commands[loop].command, command_len);
1615  if (count == command_len)
1616  {
1617  io_help_line(&local_commands[loop], output_function);
1618  found = 1;
1619  }
1620  }
1621  }
1622  loop++;
1623  }
1624  }
1625  while (local_commands[loop].function != 0L);
1626  if ((response_len != 0) && (found == 0))
1627  {
1628  (void)SHOW_ERROR("Command not found, type help for more information");
1629  }
1630  return 0;
1631 }
1632 
1633 n_int io_quit(void * ptr, n_string response, n_console_output output_function)
1634 {
1635  return 1;
1636 }
1637 
1639 {
1640  return fgets(string, (int)length, stdin);
1641 }
1642 
1644 {
1645  printf(">");
1646  return io_console_entry_clean(string, length);
1647 }
1648 
1650 {
1651  printf("%s\n", value);
1652  fflush(stdout);
1653 }
1654 
1656 {
1657  command_line_external_exit = 1;
1658 }
1659 
1660 n_int io_console(void * ptr, noble_console_command * commands, n_console_input input_function, n_console_output output_function)
1661 {
1662  n_string_block buffer;
1663 
1664  local_commands = commands;
1665 
1666  if ((input_function)(buffer, STRING_BLOCK_SIZE) != 0L)
1667  {
1668  n_int loop = 0;
1669  n_int buffer_len = io_length(buffer, STRING_BLOCK_SIZE);
1670 
1671  if ((commands[0].command == 0L) && (commands[0].function == 0L))
1672  {
1673  return SHOW_ERROR("No commands provided");
1674  }
1675 
1676  /* captures linux, mac and windows line ending issue */
1677  if (IS_RETURN(buffer[buffer_len-1]))
1678  {
1679  buffer[buffer_len-1] = 0;
1680  buffer_len--;
1681  }
1682  if (IS_RETURN(buffer[buffer_len-1]))
1683  {
1684  buffer[buffer_len-1] = 0;
1685  buffer_len--;
1686  }
1687 
1688  if (buffer_len != 0)
1689  {
1690  do
1691  {
1692  n_int command_len = io_length(commands[loop].command, 1024);
1693  n_int count = io_find((n_string)buffer, 0, buffer_len, commands[loop].command, command_len);
1694  if (count != -1)
1695  {
1696  n_int return_value;
1697  n_console * function = commands[loop].function;
1698  if (IS_SPACE(buffer[count]))
1699  {
1700  return_value = (*function)(ptr,(n_string)&buffer[count+1], output_function);
1701  if (command_line_external_exit)
1702  {
1703  return 1;
1704  }
1705  return return_value;
1706  }
1707  else if (buffer[count] == 0)
1708  {
1709  return_value = (*function)(ptr,0L, output_function);
1710  if (command_line_external_exit)
1711  {
1712  return 1;
1713  }
1714  return return_value;
1715  }
1716  }
1717  loop++;
1718  }
1719  while ((commands[loop].command != 0L) && (commands[loop].function != 0L));
1720 
1721  (void)SHOW_ERROR("Command not found, type help for more information");
1722 
1723  return 0;
1724  }
1725  else
1726  {
1727  return 0;
1728  }
1729  }
1730  return SHOW_ERROR("Console failure");
1731 }
1732 
1733 void io_string_write(n_string dest, n_string insert, n_int * pos)
1734 {
1735  n_int loop = 0;
1736  n_byte character = 127;
1737  do {
1738  character = insert [loop++];
1739  if (character)
1740  {
1741  dest[*pos] = character;
1742  *(pos) += 1;
1743  }
1744  } while (character);
1745  dest[*pos] = 0;
1746 }
1747 
1749 {
1750  n_int loop = 0;
1751  AE_ENUM local_enum;
1752  n_constant_string local_error;
1753  do
1754  {
1755  local_enum = apescript_errors[loop].enum_value;
1756  local_error = apescript_errors[loop].error_string;
1757  if (value == local_enum)
1758  {
1759  if (ptr)
1760  {
1761  SC_DEBUG_STRING(ptr, " [ ERROR : ");
1762  SC_DEBUG_STRING(ptr, local_error );
1763  SC_DEBUG_STRING(ptr," ]");
1764  SC_DEBUG_NEWLINE(ptr);
1765  SC_DEBUG_OFF(ptr);
1766  }
1767  return SHOW_ERROR(local_error);
1768  }
1769  loop++;
1770  }
1771  while((local_enum != AE_NO_ERROR) && (local_error != 0L));
1772 
1773  return io_apescript_error(ptr, AE_UNKNOWN_ERROR);
1774 }
1775 
1776 #ifdef NOBLE_APE_ASSERT
1777 
1778 void io_assert(n_string message, n_string file_loc, n_int line)
1779 {
1780  printf("Assert: %s, %s, %ld\n", message, file_loc, line);
1781 }
1782 
1783 #endif
1784 
1786 {
1787  if (entry == 1)
1788  {
1789  return 0L;
1790  }
1791  return file;
1792 }
1793 
1794 void io_file_cleanup(n_int * entry, n_file ** file)
1795 {
1796  /* This setting to zero may be duplicated in at least one place
1797  but provides additional protection - it may not be needed following
1798  a case-by-case review */
1799 
1800  *entry = 0;
1801 
1802  if (*file)
1803  {
1804  io_file_free(file);
1805  }
1806 }
1807 
1808 void io_file_writeon(n_int * entry, n_file ** file, n_byte blocked_write)
1809 {
1810  if (*entry == 0) return;
1811 #ifndef COMMAND_LINE_DEBUG
1812  if (*file == 0L) /* io_file_reused */
1813  {
1814  *file = io_file_new();
1815  }
1816  if(*file == 0L)
1817  {
1818  (void)SHOW_ERROR("Could not set up special use file");
1819  return;
1820  }
1821  if (blocked_write)
1822  {
1823  *entry = 1;
1824  }
1825  else
1826  {
1827  *entry = 2;
1828  }
1829 #endif
1830 }
1831 
1832 void io_file_writeoff(n_int * entry, n_file * file)
1833 {
1834  if (*entry == 0) return;
1835 #ifndef COMMAND_LINE_DEBUG
1836  if(file != 0L)
1837  {
1838  *entry = 0;
1839  }
1840 #endif
1841 }
1842 
1843 void io_file_string(n_int entry, n_file * file, n_constant_string string)
1844 {
1845  if (entry == 0) return;
1846 
1847  if((string != 0L)
1848 #ifndef COMMAND_LINE_DEBUG
1849  && (file != 0L)
1850 #endif
1851  )
1852  {
1853 #ifndef COMMAND_LINE_DEBUG
1854  io_write(file, string, 0);
1855 #else
1856  printf("%s",string);
1857 #endif
1858  }
1859 }
1860 
1861