📄 userio.c
字号:
/***************************************************************************** askbool* Inputs:* char *prompt: string to prompt for user input* int deflt: TRUE or FALSE default* Returns:* boolean: TRUE or FALSE as entered by user* Effect:* prompts user for yes or no input, returns result****************************************************************************/int askbool(prompt, deflt)char *prompt;int deflt;{#define undefined -1 char defchar; /* the default answer */ char c; /* user input */ char in_string[100]; int result = -1; /* the result: -1 = undefined, 0 = FALSE, 1 = TRUE */ if (deflt) defchar = 'y'; else defchar = 'n'; while (result == undefined) { gprintf(TRANS, "%s? [%c]: ", prompt, defchar); ggets(in_string); c = in_string[0]; if (islower(c)) c = toupper(c); if (c == 'Y') result = TRUE; else if (c == 'N') result = FALSE; else if (c == EOS) result = deflt; else if (abort_flag) result = deflt; /* space before Please to separate from user's type-in: */ else gprintf(TRANS, " Please type Y or N.\n"); } if (abort_flag == BREAK_LEVEL) { abort_flag = 0; result = deflt; gprintf(TRANS, "\n"); } return result;}/***************************************************************************** fileopen* Inputs:* char *deflt: the default file name (e.g. from command line)* char *extension: default extension* char *mode: read ("r") or write ("w")* char *prompt: prompt for user* Returns:* opened file pointer* Effect: * opens file, prompts for user input if necessary and warns about* possible confusion. If deflt is a null string or NULL, the user will* be prompted for a name. The routine loops until a file is opened.* If the mode is "r", a check is made to see if the file exists* with and without the extension. If both exist a warning is given.* For mode "w", a check is made to see if the file will be overwritten.* The extension is automatically added if the default or user-typed* file has no "." At the bottom of the loop body, if no file has* been opened, the user is prompted for another file name.****************************************************************************/char fileopen_name[100]; /* name of the opened file */FILE *fileopen(deflt, extension, mode, prompt) char *deflt; char *extension; /* default extension */ char *mode; /* read "r" or write "w" */ char *prompt; /* prompt for user */{ char extname[100]; /* trial name with extension added */ FILE *fp = NULL; /* file corresponding to filename */ FILE *fpext; /* file corresponding to extname */ char *problem = NULL; /* tells user why he has to try again */ if (!deflt) deflt = ""; /* treat NULL as the empty string */ strcpy(fileopen_name, deflt); /* keep trying until a good file is found: */ while (fp == NULL) { /* avoid null file names: */ while (strlen(fileopen_name) == 0) {#ifndef MACINTOSH gprintf(TRANS, "%s : ", prompt); ggets(fileopen_name); if (abort_flag) { if (abort_flag == BREAK_LEVEL) { abort_flag = 0; /* type return since user didn't... */ gprintf(TRANS, "\n"); } return NULL; }#else /* use Macintosh file dialog */ if (mode[0] == 'r') { if (!GetReadFileName(fileopen_name)) return NULL; } else if (mode[0] == 'w') { if (!(GetWriteFileName(fileopen_name, prompt))) return NULL; } else { gprintf(ERROR, "(fileopen) internal error: bad mode\n"); }#endif /* MACINTOSH */ } if (mode[0] == 'r') { strcpy(extname, fileopen_name); strcat(extname, "."); strcat(extname, extension); fp = fopen(fileopen_name, mode); fpext = fopen(extname, mode); if (fp != NULL && fpext != NULL) { gprintf(TRANS, "warning: both %s and %s exist. %s will be used.\n", fileopen_name, extname, fileopen_name); fclose(fpext); } else if (fpext != NULL) { fp = fpext; strcpy(fileopen_name, extname); /* remember what was opened */ } if (fp == NULL) problem = "Couldn't find %s.\n"; } else if (mode[0] == 'w') { boolean added_extension = FALSE; /* add the extension if there is no '.' in the file name */ if (!strchr(fileopen_name, '.')) { strcat(fileopen_name, "."); strcat(fileopen_name, extension); added_extension = TRUE; } if (TRUE#ifdef MACINTOSH /* file open dialog already asked user to confirm unless we're * adding an extension */ && added_extension#endif ) { fp = fopen(fileopen_name, "r"); if (fp != NULL) { char question[100]; fclose(fp); strcpy(question, "OK to overwrite "); strcat(question, fileopen_name); if (!askbool(question, FALSE)) { fp = NULL; problem = "\n"; goto tryagain; } } } fp = fopen(fileopen_name, mode); if (fp == NULL) problem = "Couldn't create %s.\n"; } tryagain: if (fp == NULL) { gprintf(TRANS, problem, fileopen_name); gprintf(TRANS,"Try again.\n"); fileopen_name[0] = EOS; } } return fp;}#ifdef MACINTOSHstatic int GetReadFileName(name)char *name;{ static Point p = {100,100}; SFReply loadfile; SFTypeList mytypes; mytypes[0] = 0x54455854; /* 'TEXT' */ mytypes[1] = 0x4D696469; /* 'Midi' */ mytypes[2] = 0x3F3F3F3F; /* '????' *//* could put any filter here (i.e. giofilefileter) */ SFGetFile(p, "\p", NULL, 3, mytypes, 0L, &loadfile); if (loadfile.good) { SetVol(0L,loadfile.vRefNum); PtoC_StrCopy((char *) &loadfile.fName, name); return(true); } else return(false);}static int GetWriteFileName(fn, str)char *fn, *str;{ static Point SFPwhere = { 106, 104 }; unsigned char Pstr[100], Pfn[100]; SFReply reply; strcpy((char *)Pstr, str); CtoPstr((char *)Pstr); strcpy((char *)Pfn, fn); CtoPstr((char *)Pfn); SFPutFile(SFPwhere, (ConstStr255Param) Pstr, (ConstStr255Param) Pfn, 0L, &reply); if (reply.good) { SetVol (0L,reply.vRefNum); PtoC_StrCopy((char *) &reply.fName, fn); return(true); } else return(false);}void PtoC_StrCopy(p1, p2) register char *p1, *p2;/* copies a pascal string from p1 to p2 */{ register int len; len = *p1++; while (--len>=0) *p2++=*p1++; *p2 = '\0';}boolean get_file_info(char *filename, OSType *file_type, OSType *file_creator){ short rc; /* toolbox return code */ FInfo fi; /* toolbox file info */ char fn[101]; /* temporary file name */ strcpy(fn, filename); CtoPstr(fn); if (rc = GetFInfo((byte*)fn, 0, &fi)) { gprintf(ERROR, "rc from GetFInfo=%d\n", rc); gprintf(ERROR, "unable to get file type\n"); *file_type = 0x3F3F3F3F; /* '????' */ *file_creator = 0x3F3F3F3F; /* '????' */ return FALSE; } else /* set file type & creator */ { if (debug) gprintf(TRANS, "File Type: '%.4s' File Creator: '%.4s'\n", &fi.fdType, &fi.fdCreator ); *file_type = fi.fdType; *file_creator = fi.fdCreator; } return TRUE;}boolean put_file_info(char *filename, OSType file_type, OSType file_creator){ short rc; /* toolbox return code */ FInfo fi; /* toolbox file info */ char fn[101]; /* temporary file name */ if (debug) gprintf(TRANS,"set file %s to become type '%.4s'\n", filename, &file_type); strcpy(fn, filename); CtoPstr(fn); if (rc = GetFInfo((byte*)fn, 0, &fi)) { gprintf(TRANS, "rc from GetFInfo=%d\n", rc); gprintf(TRANS, "unable to set file type\n"); } else /* set file type & creator */ { if (debug) gprintf(TRANS, "File Type: '%.4s' File Creator: '%.4s'\n", &fi.fdType, &fi.fdCreator ); fi.fdType = file_type; fi.fdCreator = file_creator; if (rc=SetFInfo((byte*)fn, 0, &fi)) { gprintf(TRANS, "rc from SetFInfo=%d\n", rc); gprintf(TRANS, "unable to set file type\n"); } else if (rc=GetFInfo((byte*)fn, 0, &fi)) { gprintf(TRANS, "rc from GetFInfo=%d\n", rc); gprintf(TRANS, "unable to verify file type\n"); } else { if (debug) gprintf(TRANS, "File Type: '%.4s' File Creator: '%.4s'\n", &fi.fdType, &fi.fdCreator ); } }}#endif /* MACINTOSH */#ifdef AMIGA/**************************************************************** ascii_signal** Input : none* Ouput : none* Return: the signal that will be raised on ascii input* Effect: none***************************************************************/UBYTE ascii_signal(){ return ConInPort->mp_SigBit;}#endif/* check_aborted -- see if any characters are available, check for ctrl C */int check_aborted(){ char in_c;#ifdef AMIGA if (GetMsg(ConInPort)) { in_c = KeyBuff[0]; if (in_c == '\r') in_c = '\n';#endif#ifndef AMIGA /* DOS or MACINTOSH or UNIX */ if (type_ahead_count < type_ahead_max && ascii_input(&in_c)) {#endif type_ahead[type_ahead_tail] = in_c; if (in_c == ABORT_CHAR) abort_flag = ABORT_LEVEL; else if (!abort_flag && in_c == BREAK_CHAR) abort_flag = BREAK_LEVEL; /* go ahead and insert anything into buffer, including ^C, ^G: */ type_ahead_count++; type_ahead_tail++; if (type_ahead_tail == type_ahead_max) type_ahead_tail = 0;#ifdef AMIGA if (type_ahead_count < type_ahead_max) ConRead();#endif } return abort_flag;} /***************************************************************************** readln* Inputs:* FILE * fp: File to read from* Effect: * Reads and discards characters until a newline is seen****************************************************************************/void readln(fp) register FILE *fp;{ register int c; while (((c = getc(fp)) != '\n') && (c != EOF)) ;}/***************************************************************************** gprintf* Inputs:* int * handler: pointer to output handler (say, a window)* or one of {TRANS, ERROR, FATAL, GDEBUG} from userio.h* char * format: a null-terminated printf style format string* int arg0 through arg14: a variable number of arguments for printf* Effect:* formats and outputs the specified information to an output handler.* this is a system-independent approach to output. On* a simple machine, it is like printf. on a more complex machine,* output is directed to the appropriate window.* Implementation* Note that to handle the variable argument list, a number of different* approaches are implemented. The first part of the implementation selects* one of 4 ways to build temp1, a formatted string. The 4 ways arise from* use or non-use of vsprintf, and use or non-use of ... in the arg list.* After building temp1, non-Amiga systems write to stdout or stderr, * whereas AMIGA writes to a special console. Why? Because the Amiga* needs a new console so we can set up a signal upon character typein.****************************************************************************/#ifndef gprintf#define GPRINTF_MESSAGE_LEN 512#ifdef USE_VSPRINTF#ifdef DOTS_FOR_ARGS/* define with ... in arg list and use vsprintf to get temp1 */public void gprintf(long where, char *format, ...){ char temp1[GPRINTF_MESSAGE_LEN];#ifdef AMIGA char temp2[GPRINTF_MESSAGE_LEN];#endif va_list ap; va_start(ap, format); vsprintf(temp1, format, ap); va_end(ap);#else /* !DOTS_FOR_ARGS *//* define with va_alist and use vsprintf to get temp1 */public void gprintf(where, format, va_alist)long where;char *format;va_dcl{ char temp1[GPRINTF_MESSAGE_LEN]; va_list pvar;/* this is a syntax error - if you don't have to remove this, *//* then this whole section of code is unnecessary. */ va_start(pvar); vsprintf(temp1, format, pvar); va_end(pvar);#endif /* DOTS_FOR_ARGS */#else /* !USE_VSPRINTF */#define MAX_GPRINTF_ARGS 10typedef struct gp_args_struct { long arg[MAX_GPRINTF_ARGS];} gp_args_node;#ifdef DOTS_FOR_ARGS/* use ... but not vsprintf */public void gprintf(long where, char *format, ...){ char temp1[GPRINTF_MESSAGE_LEN];#ifdef AMIGA char temp2[GPRINTF_MESSAGE_LEN];#endif va_list ap; gp_args_node args; va_start(ap, format); args = va_arg(ap, gp_args_node); va_end(ap);#else /* !DOTS_FOR_ARGS *//* don't use ... and don't use vsprintf */public void gprintf(where, format, args) long where; char *format; gp_args_node args;{ char temp1[GPRINTF_MESSAGE_LEN];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -