📄 rcfile.c
字号:
/* zgv 5.5 - GIF, JPEG and PBM/PGM/PPM viewer, for VGA PCs running Linux. * Copyright (C) 1993-2001 Russell Marks. See README for license details. * * rcfile.c - config file handling. */#include <stdio.h>#include <string.h>#include <stdlib.h>#include <ctype.h>#include <unistd.h> /* for getopt() */#include <vga.h>#include <vgamouse.h>#include <getopt.h>#include "rc_config.h"#include "zgv.h" /* for ZGV_VER */#include "rcfile.h"#ifndef GLASTMODE/* not sure if this is possible, but just in case... * (this is fairly conservative, of course) */#define GLASTMODE G1280x1024x16M#endifstatic int line; /* current line in config file */int in_config=0; /* true if reading config file */char *config_file_name=NULL; /* full path to config file used *//* required prototypes */void get_bool(char *arg,void *dataptr);void get_bool_and_inv(char *arg,void *dataptr);void get_int(char *arg,void *data);void get_double(char *arg,void *data);int get_modenumber(char *tptr,int *mp,int bpp_force);void get_rgbval(char *arg,void *data);void get_jis(char *arg,void *data);void do_allmodesbad(char *arg,void *data);void do_allmodesgood(char *arg,void *data);void do_badmode(char *arg,void *data);void do_goodmode(char *arg,void *data);void do_startmode(char *arg,void *data);void do_warn(char *arg,void *data);int modematch(int x, int y, int bpp);void print_version(char *arg,void *dataptr);void usage_help(char *arg,void *dataptr); struct zgv_config cfg;struct cfglookup_tag { char *name; int allow_config; /* if zero, only here for cmdline opt lookup */ void (*funcptr)(char *,void *); void *dataptr; };/* include opt/var tables generated from options.src by mkopts.awk; * rcfile_var.h has to be included after defs of above struct and * some prototypes, so may as well keep them together. */#include "rcfile_opt.h"#include "rcfile_var.h"/* and this one defines the short-option string. */#include "rcfile_short.h"/* macro for `zgv:'-ish error prefix, the format of which should * differ when reading a config file. */#define CONFIG_ERR_PREFIX() \ do \ { \ if(in_config) \ fprintf(stderr,"zgv:%s:%d: ",config_file_name,line); \ else \ fprintf(stderr,"zgv: "); \ } \ while(0)/* find next char which isn't NUL, space, or tab. */void find_token(char **ptr){while(*(*ptr) && strchr(" \t",*(*ptr))!=NULL) (*ptr)++;}int token_length(char *ptr){char *start=ptr;while(*ptr && strchr(" \t",*ptr)==NULL) ptr++;return(ptr-start);}/* returns 1 if equal, 0 otherwise */int token_compare(char *tptr,char *txt){int tlen;tlen=token_length(tptr);if(tlen!=strlen(txt)) return(0);return(strncmp(tptr,txt,tlen)==0);}void fixconfig(void){/* XXX should probably add many more to this, and perhaps give * error messages for some. */ /* don't allow funny values for this; zero is disallowed because * it could make it difficult to abort if all the files load very quickly. */if(cfg.tag_timer<=0) cfg.tag_timer=1;if(cfg.jpegspeed<1) cfg.jpegspeed=1;if(cfg.jpegspeed>3) cfg.jpegspeed=3;if(cfg.mousescale<1) cfg.mousescale=1;}void parse_config(FILE *in){static char inpline[1024];char *ptr;int f,c,inpc,found=0;line=0;while(fgets(inpline,sizeof(inpline),in)!=NULL) { line++; if(inpline[strlen(inpline)-1]=='\n') inpline[strlen(inpline)-1]=0; if((ptr=strchr(inpline,'#'))!=NULL) *ptr=0; if(*inpline) { found=0; ptr=inpline; find_token(&ptr); inpc=*ptr; for(f=0;(c=cfglookup[f].name[0]);f++) if(inpc==c && token_compare(ptr,cfglookup[f].name) && cfglookup[f].allow_config) { ptr+=token_length(ptr); /* skip current token */ find_token(&ptr); /* find next (if any) */ if(*ptr==0) ptr=NULL; /* we supply the token (or lack of one) whether they asked * for it or not - it's up to them whether to use it or ignore it. * first arg is NULL if no arg was present. */ (*cfglookup[f].funcptr)(ptr,cfglookup[f].dataptr); found=1; break; } if(!found) { CONFIG_ERR_PREFIX(); fprintf(stderr,"bad variable name.\n"); exit(1); } } }}void defaultcfg(void){int f;/* it'll use 360x480x8 if you haven't got 640x480x8, * and 320x200x8 if you've locked that out. */cfg.videomode=G640x480x256;/* for selector, it's 640x480x8 if possible, otherwise 640x480x4. */cfg.fs_startmode=G640x480x256;cfg.zoom=0;cfg.zoom_reduce_only=0;cfg.vkludge=0;cfg.brightness=0;cfg.jpeg24bit=1; /* only if possible, of course */cfg.jpegspeed=2; /* slow int by default */cfg.jpegindexstyle=2; /* jpeg thumbnail speed/quality */cfg.betterpgm=0;cfg.centreflag=1;cfg.blockcursor=0;cfg.thicktext=0;cfg.hicolmodes=0; /* don't force high-colour mode test to true */cfg.nodelprompt=0; /* default to prompting on delete */cfg.nodelprompt_tagged=0; /* prompt for tagged delete too */cfg.perfectindex=0; /* make selector cols look nice, not index cols */cfg.xvpic_index=1; /* visual index */cfg.onefile_progress=1; /* progress report while loading file given as arg */cfg.cleartext=0; /* clear text screen on startup/exit? */cfg.repeat_timer=0; /* don't reread after a timeout */cfg.tag_timer=4; /* 4 seconds per tagged file */cfg.force16fs=0; /* don't force 16-colour mode for file selector */cfg.revert=1; /* auto-reset scaling to off between pics */cfg.revert_orient=1; /* auto-reset pic orientation between pics */cfg.fakecols=1; /* try to fake more greys/colours in 8-bit modes */cfg.selecting=0; /* no selection normally */cfg.fs16col=0; /* normally use mono in 16-col file selector */cfg.viewer16col=0; /* normally use mono in 16-col viewer mode */cfg.fastdither16col=1; /* 1=use ordered dither, 0=error-diffused (in 16col) */cfg.echotagged=0; /* echo tagged files on exit */cfg.forgetoldpos=0; /* don't return to old position in revisited dir */cfg.linetext=0; /* use old line-based text instead of bitmap fonts */cfg.smallfstext=0; /* use smaller font for filenames in file selector */cfg.writefile=0;cfg.slowupdate=0;cfg.shuffleslideshow=0;cfg.scrollbar=1;cfg.mousekludge=1;cfg.mousescale=16; /* gives fair results for trackballs/mice I've tried */cfg.stupid_gnu_verbosity=0;cfg.bc_order_rev=0;cfg.xzgvkeys=0;cfg.automodefit=0;cfg.initial_picgamma=1.0;cfg.fsmagic=0;cfg.black_bg=0;cfg.auto_animate=0;cfg.contrast=(double)1;cfg.black.r =cfg.black.g =cfg.black.b = 0;cfg.dark.r =cfg.dark.g =cfg.dark.b =20;cfg.medium.r=cfg.medium.g=cfg.medium.b=30;cfg.light.r =cfg.light.g =cfg.light.b =40;cfg.marked.r=cfg.marked.g=cfg.marked.b= 0; cfg.marked.r+=30;cfg.loop=0;cfg.svgalib_mouse=0;for(f=0;f<256;f++) cfg.mode_allowed[f]=0;cfg.showxvpicdir=0;for(f=0;f<=GLASTMODE;f++) cfg.mode_allowed[f]=vga_hasmode(f)?1:0;cfg.errignore=0;cfg.pcdres=3;}void getconfig(void){static char cfgfile[1024];FILE *in;int got_rcfile=0;char *home=getenv("HOME");defaultcfg();in_config=1;*cfgfile=0;if(home && strlen(home)<sizeof(cfgfile)-strlen("/.zgvrc")-1) sprintf(cfgfile,"%s/.zgvrc",home);if((in=fopen(cfgfile,"r"))!=NULL) got_rcfile=1,config_file_name="~/.zgvrc"; /* shortened name for that */else if((in=fopen(config_file_name="/etc/zgv.conf","r"))!=NULL) got_rcfile=1;if(got_rcfile) { parse_config(in); fclose(in); }in_config=0;}void get_bool(char *arg,void *data){int *boolptr=(int *)data;if(!arg) { if(!in_config) { /* if no arg, and not in config file, set the flag. */ *boolptr=1; return; } else /* in config file, so it's an error */ { CONFIG_ERR_PREFIX(); fprintf(stderr,"option-setting arg (on/off, yes/no, ...) missing.\n"); exit(1); } }/* otherwise, set depending on value given. */if(token_compare(arg,"on") || *arg=='y' || *arg=='1') *boolptr=1;else if(token_compare(arg,"off") || *arg=='n' || *arg=='0') *boolptr=0; else { CONFIG_ERR_PREFIX(); fprintf(stderr, "bad option-setting arg\n\t(use on/off, y/n, yes/no, or 1/0).\n"); exit(1); }}void get_bool_and_inv(char *arg,void *data){int *ptr=(int *)data;int orig=*ptr;*ptr=-1; /* so we can spot changes */get_bool(arg,data);if(*ptr==-1) *ptr=orig; /* restore old val */else *ptr=!*ptr; /* invert the assignment */}void get_int(char *arg,void *data){int *ptr=(int *)data;if(arg==NULL) { CONFIG_ERR_PREFIX(); fprintf(stderr,"missing arg.\n"); exit(1); }*ptr=atoi(arg);}void get_double(char *arg,void *data){double *ptr=(double *)data;if(arg==NULL) { CONFIG_ERR_PREFIX(); fprintf(stderr,"missing arg.\n"); exit(1); }*ptr=atof(arg);}/* get mode number from something like `640 480 8' - * returns 0 if it can't find one that matches, else 1. * (the mode number is put into *mp) * * If bpp_force is non-zero, it sets the mode's bpp, overriding the * value specified in the string. */int get_modenumber(char *tptr,int *mp,int bpp_force){int x,y,bpp,rtn;if(sscanf(tptr,"%d %d %d",&x,&y,&bpp)!=3) { CONFIG_ERR_PREFIX(); fprintf(stderr,"bad or missing arg.\n"); exit(1); }if(bpp_force) bpp=bpp_force;rtn=modematch(x,y,bpp);if(rtn>=0) { *mp=rtn; return(0); }else return(-1);}void get_rgbval(char *arg,void *data){struct cfgrgb_tag *p=(struct cfgrgb_tag *)data;if(sscanf(arg,"%d %d %d",&(p->r),&(p->g),&(p->b))!=3) { CONFIG_ERR_PREFIX();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -