+/* read the file with all the pic14 definitions and pick out the definition for a processor
+ * if specified. if pic_name is NULL reads everything */
+static PIC_device *find_device(char *pic_name)
+{
+ FILE *pic_file;
+ char pic_buf[PIC14_STRING_LEN];
+ char *pic_buf_pos;
+ int found_processor = FALSE;
+ int done = FALSE;
+ char processor_name[SPLIT_WORDS_MAX][PIC14_STRING_LEN];
+ int num_processor_names = 0;
+ int pic_maxram = 0;
+ int pic_bankmsk = 0;
+ int pic_confsiz = 0;
+ int pic_program = 0;
+ int pic_data = 0;
+ int pic_eeprom = 0;
+ int pic_io = 0;
+ char *simple_pic_name;
+ char *dir;
+ char filename[512];
+ int len = 512;
+
+ /* allow abbreviations of the form "f877" - convert to "16f877" */
+ simple_pic_name = sanitise_processor_name(pic_name);
+ num_of_supported_PICS = 0;
+
+ /* open the piclist file */
+ /* first scan all include directories */
+ pic_file = NULL;
+ //fprintf( stderr, "%s: searching %s\n", __FUNCTION__, DEVICE_FILE_NAME );
+ for (dir = setFirstItem(includeDirsSet);
+ !pic_file && dir;
+ dir = setNextItem(includeDirsSet))
+ {
+ //fprintf( stderr, "searching1 %s\n", dir );
+ SNPRINTF(&filename[0], len, "%s%s%s", dir, DIR_SEPARATOR_STRING, DEVICE_FILE_NAME);
+ pic_file = fopen( filename, "rt" );
+ if (pic_file) break;
+ } // for
+ for (dir = setFirstItem(userIncDirsSet);
+ !pic_file && dir;
+ dir = setNextItem(userIncDirsSet))
+ {
+ //fprintf( stderr, "searching2 %s\n", dir );
+ SNPRINTF(&filename[0], len, "%s%s%s", dir, DIR_SEPARATOR_STRING, DEVICE_FILE_NAME);
+ pic_file = fopen( filename, "rt" );
+ if (pic_file) break;
+ } // for
+ for (dir = setFirstItem(libDirsSet);
+ !pic_file && dir;
+ dir = setNextItem(libDirsSet))
+ {
+ //fprintf( stderr, "searching3 %s\n", dir );
+ SNPRINTF(&filename[0], len, "%s%s%s", dir, DIR_SEPARATOR_STRING, DEVICE_FILE_NAME);
+ pic_file = fopen( filename, "rt" );
+ if (pic_file) break;
+ } // for
+ for (dir = setFirstItem(libPathsSet);
+ !pic_file && dir;
+ dir = setNextItem(libPathsSet))
+ {
+ //fprintf( stderr, "searching4 %s\n", dir );
+ SNPRINTF(&filename[0], len, "%s%s%s", dir, DIR_SEPARATOR_STRING, DEVICE_FILE_NAME);
+ pic_file = fopen( filename, "rt" );
+ if (pic_file) break;
+ } // for
+ if (!pic_file) {
+ pic_file = fopen(DATADIR LIB_DIR_SUFFIX DIR_SEPARATOR_STRING "pic" DIR_SEPARATOR_STRING DEVICE_FILE_NAME, "rt");
+ }
+ if (pic_file == NULL) {
+ /* this second attempt is used when initially building the libraries */
+ pic_file = fopen(".." DIR_SEPARATOR_STRING ".." DIR_SEPARATOR_STRING ".." DIR_SEPARATOR_STRING ".."
+ DIR_SEPARATOR_STRING "src" DIR_SEPARATOR_STRING "pic" DIR_SEPARATOR_STRING
+ DEVICE_FILE_NAME, "rt");
+ if (pic_file == NULL) {
+ fprintf(stderr, "can't find %s\n", DATADIR LIB_DIR_SUFFIX DIR_SEPARATOR_STRING "pic"
+ DIR_SEPARATOR_STRING DEVICE_FILE_NAME);
+ return NULL;
+ }
+ }
+
+ /* read line by line */
+ pic_buf[sizeof(pic_buf)-1] = '\0';
+ while (fgets(pic_buf, sizeof(pic_buf)-1, pic_file) != NULL && !done) {
+
+ /* remove trailing spaces */
+ while (isspace(pic_buf[strlen(pic_buf)-1]))
+ pic_buf[strlen(pic_buf)-1] = '\0';
+
+ /* remove leading spaces */
+ for (pic_buf_pos = pic_buf; isspace(*pic_buf_pos); pic_buf_pos++)
+ {}
+
+ /* ignore comment / empty lines */
+ if (*pic_buf_pos != '\0' && *pic_buf_pos != '#') {
+
+ /* split into fields */
+ char pic_word[SPLIT_WORDS_MAX][PIC14_STRING_LEN];
+ int num_pic_words;
+ int wcount;
+
+ num_pic_words = split_words(pic_word, pic_buf_pos);
+
+ if (STRCASECMP(pic_word[0], "processor") == 0) {
+
+ if (pic_name == NULL) {
+ /* this is the mode where we read all the processors in - store the names for now */
+ if (num_processor_names > 0) {
+ /* store away all the previous processor definitions */
+ int dcount;
+
+ for (dcount = 1; dcount < num_processor_names; dcount++)
+ create_pic(processor_name[dcount], pic_maxram, pic_bankmsk,
+ pic_confsiz, pic_program, pic_data, pic_eeprom, pic_io);
+ }
+
+ num_processor_names = split_words(processor_name, pic_buf_pos);
+ }
+ else {
+ /* if we've just completed reading a processor definition stop now */
+ if (found_processor)
+ done = TRUE;
+ else {
+ /* check if this processor name is a match */
+ for (wcount = 1; wcount < num_pic_words; wcount++) {
+
+ /* skip uninteresting prefixes */
+ char *found_name = sanitise_processor_name(pic_word[wcount]);
+
+ if (STRCASECMP(found_name, simple_pic_name) == 0)
+ found_processor = TRUE;
+ }
+ }
+ }
+ }
+
+ else {
+ if (found_processor || pic_name == NULL) {
+ /* only parse a processor section if we've found the one we want */
+ if (STRCASECMP(pic_word[0], "maxram") == 0 && num_pic_words > 1) {
+ pic_maxram = parse_config_value(pic_word[1]);
+ setMaxRAM(pic_maxram);
+ }
+ else if (STRCASECMP(pic_word[0], "bankmsk") == 0 && num_pic_words > 1)
+ pic_bankmsk = parse_config_value(pic_word[1]);
+
+ else if (STRCASECMP(pic_word[0], "confsiz") == 0 && num_pic_words > 1)
+ pic_confsiz = parse_config_value(pic_word[1]);
+
+ else if (STRCASECMP(pic_word[0], "program") == 0 && num_pic_words > 1)
+ pic_program = parse_config_value(pic_word[1]);
+
+ else if (STRCASECMP(pic_word[0], "data") == 0 && num_pic_words > 1)
+ pic_data = parse_config_value(pic_word[1]);
+
+ else if (STRCASECMP(pic_word[0], "eeprom") == 0 && num_pic_words > 1)
+ pic_eeprom = parse_config_value(pic_word[1]);
+
+ else if (STRCASECMP(pic_word[0], "io") == 0 && num_pic_words > 1)
+ pic_io = parse_config_value(pic_word[1]);
+
+ else if (STRCASECMP(pic_word[0], "regmap") == 0 && num_pic_words > 2) {
+ if (found_processor)
+ register_map(num_pic_words, pic_word);
+ }
+ else if (STRCASECMP(pic_word[0], "memmap") == 0 && num_pic_words > 2) {
+ if (found_processor)
+ ram_map(num_pic_words, pic_word);
+ }
+ else {
+ fprintf(stderr, "WARNING: %s: bad syntax `%s'\n", DEVICE_FILE_NAME, pic_word[0]);
+ }
+ }
+ }
+ }
+ }
+
+ fclose(pic_file);