home *** CD-ROM | disk | FTP | other *** search
- /* (c) Marietta Systems, Inc 1987
- * All rights reserved */
- /*
- * This program sets up the dictionary for a dBase3+ file
- *
- * The maximum number of fields is 20, and memo fields are not supported
- */
- #include "mtest.h"
- int dbf_cr(char*);
- int dbf_init(int*, struct DBF_DEF*, char*, int);
- int dbf_name(byte*);
- void linedisp(struct DBF_DEF*, int);
- int lineacpt(struct DBF_DEF*, int);
- void lineshuf(struct DBF_DEF*, int, int);
- #define point "\075\020"
- /*
- *
- * Function to create dbase3+ file & setup data dictionary
- *
- */
- int dbf_cr(name)
- char *name;{
- struct DBF_DEF format[20];
- int fields = 0, fld = 0, fh = fileopen(name, dbase3, recreate), z, ret;
- byte kk = 0;
- if (fh < 0) return fh;
- /* setup */
- for (z = 0; z < 20; format[z++].dbf_type = 'C')
- format[z].dbf_name[0] = format[z].dbf_len = format[z].dbf_dec = 0;
- /* setup function key map */
- KEYMATCH[0] = 0X430; /* Up & right arrow, Ctrl+Enter */
- KEYMATCH[1] = 0X108; /* Down & left arrow */
- KEYMATCH[2] = KEYMATCH[3] = KEYMATCH[6] = KEYMATCH[7] = 0;
- KEYMATCH[4] = 0X3000; /* F5, F6 */
- disp_err("",1); /* force display of new function keys */
- if (1 > mk_wndw(TOP_LINE + 1, 1, SCRN_LEN - 1, 80,
- "Enter data dictionary details for dBase3+ file")) goodbye(13);
- kk = INSERT; /* must first insert into an empty dictionary */
- linedisp(format, 0);
- /* main accept loop */
- for(;;){
- if (!kk) linedisp(format, fld);
- display(point, fld+1, 5, blink);
- set_crsr(fld+1, 1);
- if (!kk) kk = grabchar();
- display(": ", fld+1, 5, high);
- switch((int)kk){
- case CRS_UP: if (fld) fld--; kk = 0; break;
- case CRS_DN: if (fld < 20 && fld < fields) fld++;
- kk = 0; break;
- case CRS_RT: case ENTER: case TAB:
- if (fld == fields) {kk = INSERT; break;}
- if ((ret = lineacpt(format, fld)) < 0) goodbye(11);
- kk = (ret ? INCHAR : 0);
- if (format[fld].dbf_name[0] == 0 && fields != fld)
- {lineshuf(format, fld, 1); fields--;}
- break;
- case QUIT: kk = 0; break;
- case INSERT: if (fields >= 20)
- {disp_err("No more fields allowed",1); break;}
- if (fld < fields) lineshuf(format, fld, -1);
- if ((ret = lineacpt(format, fld)) < 0) goodbye(11);
- kk = (ret ? INCHAR : 0);
- if (format[fld].dbf_name[0] == 0)
- lineshuf(format, fld, 1);
- else {fld++; fields++;}
- if (!kk && fld >= fields - 1) kk = INSERT;
- break;
- case DELETE:if (fields && fld < fields)
- {lineshuf(format, fld, 1); fields--;}
- kk = 0; break;
- case HELP: if (mk_wndw(3,48,13,80,"Dictionary help") > 1){
- display("To change a line, move the ",1,1,high);
- display(" cursor with the up and down ",2,1,high);
- display(" keys, then make your selec- ",3,1,high);
- display(" tion with the Enter key. ",4,1,high);
- display("To insert a line press F5 key ",5,1,high);
- display("To delete a line press F6 key ",6,1,high);
- display("To exit, press the F10 key ",7,1,high);
- display("<< Press ESC key to continue>>",9,1,low);
- while(grabchar() != ESC)
- disp_err("Press ESC key", 2);
- rm_wndw();
- }
- kk = 0; break;
- default: warble(1000); idleloop(ERR_BEEP); warble(0);
- kk = 0; break;
- } /* end switch */
- if (INCHAR == QUIT && disp_qry("Have you completed entry"))
- break;
- } /* end for loop */
- ret = ((fields && disp_qry("Write the dictionary to file")) ?
- dbf_init(&fh, format, name, fields) : -1);
- fileclos(fh); rm_wndw(); return ret;
- } /* end function dbf_cr */
- /*
- *
- * Function to write dictionary to new dbase3+ file
- *
- */
- int dbf_init(fh, format, name, fields)
- int *fh, fields;
- struct DBF_DEF *format;
- char *name;{
- int z;
- short *sptr;
- long rec_nbr = 0L;
- fileinit(*fh, 0, 32, 0L); /* nil start, 32 byte record file */
- memset(FN[*fh].record, 0, 32);
- /* write the system header 32 byte record */
- FN[*fh].record[0] = SYS_REC;
- sptr = (short *) &FN[*fh].record[8];
- sptr[0] = fields * 32 + 33; /* start of data */
- for (sptr[1] = 1, z = 0 ; z < fields ; z++)
- {sptr[1] += format[z].dbf_len;} /* data record length */
- if (filewrit(*fh, &rec_nbr) < 0) goto error;
- /* write the field dictionary records */
- for (z = 0 ; z < fields ; z++){
- memset(FN[*fh].record, 0, 32);
- memcpy(FN[*fh].record, format[z].dbf_name, 11);
- FN[*fh].record[11] = format[z].dbf_type;
- FN[*fh].record[16] = format[z].dbf_len;
- FN[*fh].record[17] = format[z].dbf_dec;
- if (filewrit(*fh, &rec_nbr) < 0) goto error;
- }
- /* write the dBase3+ header terminator */
- FN[*fh].rec_len = 1; /* hairy but necessary technique here */
- FN[*fh].record[0] = 0X0D;
- if (filewrit(*fh, &rec_nbr) < 0) goto error;
- FN[*fh].rec_len = 32;
- FN[*fh].prime = 0L; /* set file record count back to zero */
- return 0;
- error: fileclos(*fh);
- disp_msg("Terminate?? in dbf_init ",(int)rec_nbr + 100); read_kb();
- *fh = fileopen(name, dbase3, recreate);
- return -1;
- } /* end function dbf_init */
- /*
- *
- * Function to display line of data dictionary
- *
- */
- void linedisp(format, line)
- struct DBF_DEF *format;
- int line; {
- byte text[12];
- display("Name: ", line + 1, 1, high);
- justify(left, text, format[line].dbf_name, 10, 0);
- display(text, 0, 0, ACC_DISP);
- display(" Type: ", 0, 0, high);
- switch((int)format[line].dbf_type){
- case 0:
- case 32:
- case 'C':display("Character", 0, 0, ACC_DISP); break;
- case 'D':display("Date ", 0, 0, ACC_DISP); break;
- case 'L':display("Logical ", 0, 0, ACC_DISP); break;
- case 'M':display("Memo ", 0, 0, ACC_DISP); break;
- case 'N':display("Numeric ", 0, 0, ACC_DISP); break;
- default: display("?????????", 0, 0, ACC_DISP); break;
- }
- display(" Size: ", 0, 0, high);
- if (format[line].dbf_type == 'N')
- sprintf(text,"%3u %u",format[line].dbf_len, format[line].dbf_dec);
- else sprintf(text, "%3u ", format[line].dbf_len);
- display(text, 0, 0, ACC_DISP); display(" ", line+1, 45, low);
- } /* end function linedisp */
- /*
- *
- * Function to validate a dbase3+ field name
- *
- */
- int dbf_name (name)
- byte *name;{
- int z, len;
- concat(name, 0); /* strip trailing spaces */
- strupr(name); /* turn alpha characters into uppercase */
- len = strlen(name);
- if (len > 10 || !len || !isalpha(name[0])) goto error;
- for (z = 1 ; z < len ; z++)
- if (!isalpha(name[z]) && !isdigit(name[z]) && name[z] != '_')
- goto error;
- return 1;
- error: disp_err("Invalid character in fieldname",3);
- return 0;
- }
- /*
- *
- * Function to accept a new line in dictionary
- *
- */
- #define CR_MSG0 " "
- #define CR_MSG1 " Char, Date, Logical, Numeric "
- #define CR_MSG2 " Maximum of 254 bytes in size "
- #define CR_MSG3 " Maximum of 32 bytes in Numeric"
- #define CR_MSG4 " Maximum of 8 decimal places "
- #define CR_MSG5 " Only A - Z, 0 - 9, and _ "
- int lineacpt(format, fld)
- struct DBF_DEF *format;
- int fld;{
- int ret, ans, z;
- char text[12];
- /* */
- name: display(CR_MSG5, fld+1, 48, low);
- set_crsr(fld+1, 7);
- ret = accept(format[fld].dbf_name, left, alt_reverse, 10, 0);
- if (ret && INCHAR != CRS_RT) goto end;
- if (!dbf_name(format[fld].dbf_name)) goto name;
- display(format[fld].dbf_name, fld+1, 7, ACC_DISP);
- for (z = 0 ; z < 20 ; z++)
- if (z != fld && !strcmp((byte*)format[fld].dbf_name,
- (byte*)format[z].dbf_name))
- {disp_err("Duplicate name",3); goto name;}
- /* */
- type: display(CR_MSG1, fld+1, 48, low);
- set_crsr(fld+1, 25);
- text[0] = format[fld].dbf_type; text[1] = 0;
- ret = accept(text, left, alt_reverse, 1, 0);
- if (ret) if (INCHAR == CTL_ENT || INCHAR == CRS_LT) goto name;
- else if (INCHAR != CRS_RT) goto end;
- format[fld].dbf_type = text[0] = toupper(text[0]);
- /* */
- switch ((int)text[0]){
- case 'C': display("Character", fld+1, 25, ACC_DISP);
- sprintf(text, "%3u", format[fld].dbf_len);
- c_size: display(CR_MSG2, fld+1, 48, low);
- set_crsr(fld+1, 42);
- ret = accept(text, code, alt_low, 3, 0);
- if (ret) if (INCHAR == CTL_ENT || INCHAR == CRS_LT)
- goto type;
- else break;
- if ((ans = atoi(text)) > 254 || !ans)
- {disp_err("size must be 1 thru 254", 1); goto c_size;}
- format[fld].dbf_len = ans;
- break;
- case 'D': break;
- case 'L': break;
- case 'N': display("Numeric ", fld+1, 25, ACC_DISP);
- n1_size: sprintf(text, "%3u", format[fld].dbf_len);
- display(CR_MSG3, fld+1, 48, low);
- set_crsr(fld+1, 42);
- ret = accept(text, code, alt_low, 3, 0);
- if (ret) if (INCHAR == CTL_ENT || INCHAR == CRS_LT)
- goto type;
- else if (INCHAR != CRS_RT) break;
- if ((ans = atoi(text)) > 32 || !ans)
- {disp_err("size must be 1 thru 32", 1); goto n1_size;}
- format[fld].dbf_len = ans;
- n2_size: sprintf(text, "%1u", format[fld].dbf_dec);
- display(CR_MSG4, fld+1, 48, low);
- set_crsr(fld+1, 46);
- ret = accept(text, code, alt_low, 1, 0);
- if (ret) if (INCHAR == CTL_ENT || INCHAR == CRS_LT)
- goto n1_size;
- else break;
- if ((ans = atoi(text)) > 8)
- {disp_err("Maximum of 8 decimal places", 1);
- goto n2_size;}
- format[fld].dbf_dec = ans;
- break;
- default: disp_err("Invalid type selection", 1); goto type;
- } /* end switch */
- /* exit validation */
- end: if (!format[fld].dbf_name[0]) return ret; /* empty */
- switch((int)format[fld].dbf_type){
- case 'C': format[fld].dbf_dec = 0;
- if (format[fld].dbf_len == 255) goto c_size;
- break;
- case 'D': format[fld].dbf_len = 8;
- format[fld].dbf_dec = 0; break;
- case 'L': format[fld].dbf_len = 1;
- format[fld].dbf_dec = 0; break;
- case 'N': if (format[fld].dbf_len > 32) goto n1_size;
- if (format[fld].dbf_dec > 8) goto n2_size;
- if (format[fld].dbf_dec + 2 > format[fld].dbf_len)
- goto n1_size;
- break;
- default: goto type;
- } /* end switch */
- display(CR_MSG0, fld+1, 48, low); /* blank out help area */
- if (!format[fld].dbf_len) memset(format[fld].dbf_name, 0, 11);
- linedisp(format, fld);
- return ret;
- } /* end function lineacpt */
- /*
- *
- * Function to shuffle up and down the dictionary display
- *
- */
- void lineshuf(format, fld, up)
- struct DBF_DEF *format;
- int fld, up;{
- int to, from, base;
- up = (up < 0 ? -1 : 1);
- scroll(up, fld); /* scroll window up or down */
- to = (up > 0 ? fld : 19);
- from = (up > 0 ? fld + 1 : 18);
- base = (up > 0 ? 19 : fld);
- for (; base != to ; to += up, from += up){
- memcpy(format[to].dbf_name, format[from].dbf_name, 11);
- format[to].dbf_type = format[from].dbf_type;
- format[to].dbf_len = format[from].dbf_len;
- format[to].dbf_dec = format[from].dbf_dec;
- }
- memset(format[to].dbf_name, 0, 11);
- format[to].dbf_type = 'C';
- format[to].dbf_len = 0;
- format[to].dbf_dec = 0;
- if (up < 0) linedisp(format, fld);
- } /* end function lineshuf */
- /*
- *
- * Main section
- *
- */
- void main(){
- char name[51];
- int z, fh;
- clr_scrn("dBase3+ dictionary create");
- strcpy(name, "dbftest.dbf");
- for (;;){
- for (z = 0 ; z < 8 ; KEYMATCH[z++] = 0); disp_err("",1);
- display("Enter file name ", 20, 2, low);
- if (accept(name, left, alt_reverse, 50, 0)) goodbye(0);
- if ((fh = fileopen(name, dbase3, readonly)) < 0) continue;
- if (fh && FN[fh].fnext != NULL
- && !disp_qry("Do you wish to overwrite file"))
- {fileclos(fh); continue;}
- else if (fh) {fileclos(fh); if (fileback(name) < 1) continue;}
- if (!dbf_cr(name)) {name[0] = 0; disp_err("Dictionary created", 1);}
- else disp_err("Error end to dict create", 2);
- }
- }