From 6195da85a3c11b3c8ac195ff5ef08c69e6f968e8 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 2 Jul 2008 15:59:29 +0000 Subject: zr36067: Delete dead code From: Jean Delvare This has been commented out for years, it's about time to get rid of it. Signed-off-by: Jean Delvare Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/zoran_card.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/linux/drivers/media/video/zoran_card.c b/linux/drivers/media/video/zoran_card.c index 56d8edecc..cc45ae5cd 100644 --- a/linux/drivers/media/video/zoran_card.c +++ b/linux/drivers/media/video/zoran_card.c @@ -359,14 +359,6 @@ i2cid_to_modulename (u16 i2c_id) case I2C_DRIVERID_VPX3220: name = "vpx3220"; break; -/* case I2C_DRIVERID_VPX3224: - name = "vpx3224"; - break; - case I2C_DRIVERID_MSE3000: - name = "mse3000"; - break;*/ - default: - break; } return name; @@ -387,8 +379,6 @@ codecid_to_modulename (u16 codecid) case CODEC_TYPE_ZR36016: name = "zr36016"; break; - default: - break; } return name; @@ -429,7 +419,6 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { .type = DC10_old, .name = "DC10(old)", .i2c_decoder = I2C_DRIVERID_VPX3220, - /*.i2c_encoder = I2C_DRIVERID_MSE3000,*/ .video_codec = CODEC_TYPE_ZR36050, .video_vfe = CODEC_TYPE_ZR36016, -- cgit v1.2.3 From 09524e72d1ea817fdbbd18d7219b824588d66278 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 2 Jul 2008 16:01:21 +0000 Subject: bt819: Fix a debug message From: Jean Delvare Signed-off-by: Jean Delvare Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/bt819.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux/drivers/media/video/bt819.c b/linux/drivers/media/video/bt819.c index 402bccaf7..90be239cc 100644 --- a/linux/drivers/media/video/bt819.c +++ b/linux/drivers/media/video/bt819.c @@ -517,7 +517,7 @@ bt819_detect_client (struct i2c_adapter *adapter, dprintk(1, KERN_INFO - "saa7111.c: detecting bt819 client on address 0x%x\n", + "bt819: detecting bt819 client on address 0x%x\n", address << 1); /* Check if the adapter supports the needed features */ -- cgit v1.2.3 From 40623bc5fb02d968ab90fbe4479458cda3ef6f52 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 30 Jun 2008 21:28:34 +0000 Subject: Sensoray 2255 V4l driver checkpatch fixes From: Dean Anderson This patch fixes some coding style issues. It also fixes a NULL de-reference on driver unload. The permissions for the module parameters were changed to 0644. Signed-off-by: Dean Anderson Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/s2255drv.c | 61 +++++++++++++++++++++--------------- 1 file changed, 35 insertions(+), 26 deletions(-) diff --git a/linux/drivers/media/video/s2255drv.c b/linux/drivers/media/video/s2255drv.c index aca8c3d90..6eb396ffc 100644 --- a/linux/drivers/media/video/s2255drv.c +++ b/linux/drivers/media/video/s2255drv.c @@ -68,17 +68,17 @@ /* maximum time for DSP to start responding after last FW word loaded(ms) */ #define S2255_DSP_BOOTTIME 400 /* maximum time to wait for firmware to load (ms) */ -#define S2255_LOAD_TIMEOUT (5000+S2255_DSP_BOOTTIME) +#define S2255_LOAD_TIMEOUT (5000 + S2255_DSP_BOOTTIME) #define S2255_DEF_BUFS 16 #define MAX_CHANNELS 4 #define FRAME_MARKER 0x2255DA4AL -#define MAX_PIPE_USBBLOCK (40*1024) -#define DEFAULT_PIPE_USBBLOCK (16*1024) +#define MAX_PIPE_USBBLOCK (40 * 1024) +#define DEFAULT_PIPE_USBBLOCK (16 * 1024) #define MAX_CHANNELS 4 #define MAX_PIPE_BUFFERS 1 #define SYS_FRAMES 4 /* maximum size is PAL full size plus room for the marker header(s) */ -#define SYS_FRAMES_MAXSIZE (720*288*2*2 + 4096) +#define SYS_FRAMES_MAXSIZE (720 * 288 * 2 * 2 + 4096) #define DEF_USB_BLOCK (4096) #define LINE_SZ_4CIFS_NTSC 640 #define LINE_SZ_2CIFS_NTSC 640 @@ -169,7 +169,7 @@ struct s2255_bufferi { #define DEF_MODEI_NTSC_CONT {FORMAT_NTSC, DEF_SCALE, DEF_COLOR, \ DEF_FDEC, DEF_BRIGHT, DEF_CONTRAST, DEF_SATURATION, \ - DEF_HUE, 0, DEF_USB_BLOCK, 0 } + DEF_HUE, 0, DEF_USB_BLOCK, 0} struct s2255_dmaqueue { struct list_head active; @@ -276,6 +276,10 @@ struct s2255_fh { struct s2255_mode mode; }; +/* + * TODO: fixme S2255_MAX_USERS. Do not limit open driver handles. + * Limit V4L to one stream at a time. + */ #define S2255_MAX_USERS 1 #define CUR_USB_FWVER 774 /* current cypress EEPROM firmware version */ @@ -294,7 +298,7 @@ struct s2255_fh { #define PREFIX_SIZE 512 /* Channels on box are in reverse order */ -static unsigned long G_chnmap[MAX_CHANNELS] = { 3, 2, 1, 0 }; +static unsigned long G_chnmap[MAX_CHANNELS] = {3, 2, 1, 0}; static LIST_HEAD(s2255_devlist); @@ -330,11 +334,11 @@ static unsigned int vid_limit = 16; /* Video memory limit, in Mb */ /* start video number */ static int video_nr = -1; /* /dev/videoN, -1 for autodetect */ -module_param(debug, int, 0); +module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Debug level(0-100) default 0"); -module_param(vid_limit, int, 0); +module_param(vid_limit, int, 0644); MODULE_PARM_DESC(vid_limit, "video memory limit(Mb)"); -module_param(video_nr, int, 0); +module_param(video_nr, int, 0644); MODULE_PARM_DESC(video_nr, "start video minor(-1 default autodetect)"); /* USB device table */ @@ -438,7 +442,10 @@ static int norm_minh(struct video_device *vdev) } -/* converts 2255 planar format to yuyv or uyvy */ +/* + * TODO: fixme: move YUV reordering to hardware + * converts 2255 planar format to yuyv or uyvy + */ static void planar422p_to_yuv_packed(const unsigned char *in, unsigned char *out, int width, int height, @@ -503,7 +510,7 @@ static void s2255_fwchunk_complete(struct urb *urb) struct usb_device *udev = urb->dev; int len; dprintk(100, "udev %p urb %p", udev, urb); - + /* TODO: fixme. reflect change in status */ if (urb->status) { dev_err(&udev->dev, "URB failed with status %d", urb->status); return; @@ -683,7 +690,7 @@ static int buffer_setup(struct videobuf_queue *vq, unsigned int *count, if (0 == *count) *count = S2255_DEF_BUFS; - while (*size * *count > vid_limit * 1024 * 1024) + while (*size * (*count) > vid_limit * 1024 * 1024) (*count)--; return 0; @@ -790,7 +797,7 @@ static int res_get(struct s2255_dev *dev, struct s2255_fh *fh) static int res_locked(struct s2255_dev *dev, struct s2255_fh *fh) { - return (dev->resources[fh->channel]); + return dev->resources[fh->channel]; } static void res_free(struct s2255_dev *dev, struct s2255_fh *fh) @@ -807,7 +814,8 @@ static int vidioc_querycap(struct file *file, void *priv, struct s2255_dev *dev = fh->dev; strlcpy(cap->driver, "s2255", sizeof(cap->driver)); strlcpy(cap->card, "s2255", sizeof(cap->card)); - strlcpy(cap->bus_info, dev_name(&dev->udev->dev), sizeof(cap->bus_info)); + strlcpy(cap->bus_info, dev_name(&dev->udev->dev), + sizeof(cap->bus_info)); cap->version = S2255_VERSION; cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; return 0; @@ -840,8 +848,7 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, f->fmt.pix.pixelformat = fh->fmt->fourcc; f->fmt.pix.bytesperline = f->fmt.pix.width * (fh->fmt->depth >> 3); f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; - - return (0); + return 0; } static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, @@ -962,7 +969,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, ret = vidioc_try_fmt_vid_cap(file, fh, f); if (ret < 0) - return (ret); + return ret; fmt = format_by_fourcc(f->fmt.pix.pixelformat); @@ -1337,7 +1344,7 @@ static int vidioc_enum_input(struct file *file, void *priv, inp->type = V4L2_INPUT_TYPE_CAMERA; inp->std = S2255_NORMS; strlcpy(inp->name, "Camera", sizeof(inp->name)); - return (0); + return 0; } static int vidioc_g_input(struct file *file, void *priv, unsigned int *i) @@ -1361,7 +1368,7 @@ static int vidioc_queryctrl(struct file *file, void *priv, for (i = 0; i < ARRAY_SIZE(s2255_qctrl); i++) if (qc->id && qc->id == s2255_qctrl[i].id) { memcpy(qc, &(s2255_qctrl[i]), sizeof(*qc)); - return (0); + return 0; } dprintk(4, "query_ctrl -EINVAL %d\n", qc->id); @@ -1376,7 +1383,7 @@ static int vidioc_g_ctrl(struct file *file, void *priv, for (i = 0; i < ARRAY_SIZE(s2255_qctrl); i++) if (ctrl->id == s2255_qctrl[i].id) { ctrl->value = qctl_regs[i]; - return (0); + return 0; } dprintk(4, "g_ctrl -EINVAL\n"); @@ -1396,7 +1403,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv, if (ctrl->id == s2255_qctrl[i].id) { if (ctrl->value < s2255_qctrl[i].minimum || ctrl->value > s2255_qctrl[i].maximum) - return (-ERANGE); + return -ERANGE; qctl_regs[i] = ctrl->value; /* update the mode to the corresponding value */ @@ -1572,6 +1579,11 @@ static void s2255_destroy(struct kref *kref) usb_free_urb(dev->fw_data->fw_urb); dev->fw_data->fw_urb = NULL; } + /* + * TODO: fixme(above, below): potentially leaving timers alive. + * do not ignore timeout below if + * it occurs. + */ /* make sure we aren't waiting for the DSP */ if (atomic_read(&dev->fw_data->fw_state) == S2255_FW_LOADED_DSPWAIT) { @@ -1583,15 +1595,12 @@ static void s2255_destroy(struct kref *kref) } if (dev->fw_data) { + if (dev->fw_data->fw) + release_firmware(dev->fw_data->fw); kfree(dev->fw_data->pfw_data); kfree(dev->fw_data); } - if (dev->fw_data->fw) { - release_firmware(dev->fw_data->fw); - dev->fw_data->fw = NULL; - } - usb_put_dev(dev->udev); dprintk(1, "%s", __func__); kfree(dev); -- cgit v1.2.3 From 5d6597046c8d57aa650a06343c4d63ba7dbe57dc Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 30 Jun 2008 20:57:39 +0000 Subject: OV7670: don't reject unsupported settings From: Daniel Drake For VIDIOC_G_FMT/VIDIOC_TRY_FMT, the V4L2 API spec states: "Drivers should not return an error code unless the input is ambiguous" "Very simple, inflexible devices may even ignore all input and always return the default parameters." "When the requested buffer type is not supported drivers return an EINVAL error code." i.e. returning errors for unsupported fields is bad, and it's ok to unconditionally overwrite user-requested settings This patch makes ov7670 meet that behaviour, and brings it in line with other drivers e.g. stk-webcam. It also fixes compatibility with (unpatched) gstreamer. Signed-off-by: Daniel Drake Acked-by: Jonathan Corbet Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/ov7670.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/linux/drivers/media/video/ov7670.c b/linux/drivers/media/video/ov7670.c index f226161bc..dcf7678a8 100644 --- a/linux/drivers/media/video/ov7670.c +++ b/linux/drivers/media/video/ov7670.c @@ -704,17 +704,17 @@ static int ov7670_try_fmt(struct i2c_client *c, struct v4l2_format *fmt, for (index = 0; index < N_OV7670_FMTS; index++) if (ov7670_formats[index].pixelformat == pix->pixelformat) break; - if (index >= N_OV7670_FMTS) - return -EINVAL; + if (index >= N_OV7670_FMTS) { + /* default to first format */ + index = 0; + pix->pixelformat = ov7670_formats[0].pixelformat; + } if (ret_fmt != NULL) *ret_fmt = ov7670_formats + index; /* * Fields: the OV devices claim to be progressive. */ - if (pix->field == V4L2_FIELD_ANY) - pix->field = V4L2_FIELD_NONE; - else if (pix->field != V4L2_FIELD_NONE) - return -EINVAL; + pix->field = V4L2_FIELD_NONE; /* * Round requested image size down to the nearest * we support, but not below the smallest. -- cgit v1.2.3 From 58cfc4da3781701f2b8da0d4cb6618b6179f223e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 12 Jul 2008 09:27:59 -0300 Subject: saa7134: Add support for analog only ASUSTeK P7131 From: Hermann Pitton saa7134: add a separate entry for the ASUSTeK P7131 analog only and do some eeprom detection to escape from the TVFM35 with the same PCI subsystem on auto detection. Signed-off-by: Hermann Pitton Signed-off-by: Mauro Carvalho Chehab --- linux/Documentation/video4linux/CARDLIST.saa7134 | 1 + linux/drivers/media/video/saa7134/saa7134-cards.c | 43 +++++++++++++++++++++++ linux/drivers/media/video/saa7134/saa7134-input.c | 1 + linux/drivers/media/video/saa7134/saa7134.h | 1 + 4 files changed, 46 insertions(+) diff --git a/linux/Documentation/video4linux/CARDLIST.saa7134 b/linux/Documentation/video4linux/CARDLIST.saa7134 index 171905e87..39868af9c 100644 --- a/linux/Documentation/video4linux/CARDLIST.saa7134 +++ b/linux/Documentation/video4linux/CARDLIST.saa7134 @@ -144,3 +144,4 @@ 143 -> Beholder BeholdTV M63 [5ace:6191] 144 -> Beholder BeholdTV M6 Extra [5ace:6193] 145 -> AVerMedia MiniPCI DVB-T Hybrid M103 [1461:f636] +146 -> ASUSTeK P7131 Analog diff --git a/linux/drivers/media/video/saa7134/saa7134-cards.c b/linux/drivers/media/video/saa7134/saa7134-cards.c index a2a4ca6f8..0d4dca518 100644 --- a/linux/drivers/media/video/saa7134/saa7134-cards.c +++ b/linux/drivers/media/video/saa7134/saa7134-cards.c @@ -3558,6 +3558,39 @@ struct saa7134_board saa7134_boards[] = { .amux = TV, .gpio = 0x0200000, }, + }, + [SAA7134_BOARD_ASUSTeK_P7131_ANALOG] = { + .name = "ASUSTeK P7131 Analog", + .audio_clock = 0x00187de7, + .tuner_type = TUNER_PHILIPS_TDA8290, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .gpiomask = 1 << 21, + .inputs = {{ + .name = name_tv, + .vmux = 1, + .amux = TV, + .tv = 1, + .gpio = 0x0000000, + }, { + .name = name_comp1, + .vmux = 3, + .amux = LINE2, + }, { + .name = name_comp2, + .vmux = 0, + .amux = LINE2, + }, { + .name = name_svideo, + .vmux = 8, + .amux = LINE2, + } }, + .radio = { + .name = name_radio, + .amux = TV, + .gpio = 0x0200000, + }, }, [SAA7134_BOARD_SABRENT_TV_PCB05] = { .name = "Sabrent PCMCIA TV-PCB05", @@ -5704,6 +5737,7 @@ int saa7134_board_init1(struct saa7134_dev *dev) case SAA7134_BOARD_FLYDVBT_LR301: case SAA7134_BOARD_ASUSTeK_P7131_DUAL: case SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA: + case SAA7134_BOARD_ASUSTeK_P7131_ANALOG: case SAA7134_BOARD_FLYDVBTDUO: case SAA7134_BOARD_PROTEUS_2309: case SAA7134_BOARD_AVERMEDIA_A16AR: @@ -6044,6 +6078,15 @@ int saa7134_board_init2(struct saa7134_dev *dev) i2c_transfer(&dev->i2c_adap, &msg, 1); break; } + case SAA7134_BOARD_ASUSTeK_TVFM35: + /* The card below is detected as card=53, but is different */ + if (dev->autodetected && (dev->eedata[0x27] == 0x03)) { + dev->board = SAA7134_BOARD_ASUSTeK_P7131_ANALOG; + printk(KERN_INFO "%s: P7131 analog only, using " + "entry of %s\n", + dev->name, saa7134_boards[dev->board].name); + } + break; case SAA7134_BOARD_HAUPPAUGE_HVR1110: hauppauge_eeprom(dev, dev->eedata+0x80); /* break intentionally omitted */ diff --git a/linux/drivers/media/video/saa7134/saa7134-input.c b/linux/drivers/media/video/saa7134/saa7134-input.c index 0ad81e690..89fc7dfc2 100644 --- a/linux/drivers/media/video/saa7134/saa7134-input.c +++ b/linux/drivers/media/video/saa7134/saa7134-input.c @@ -409,6 +409,7 @@ int saa7134_input_init1(struct saa7134_dev *dev) break; case SAA7134_BOARD_ASUSTeK_P7131_DUAL: case SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA: + case SAA7134_BOARD_ASUSTeK_P7131_ANALOG: ir_codes = ir_codes_asus_pc39; mask_keydown = 0x0040000; rc5_gpio = 1; diff --git a/linux/drivers/media/video/saa7134/saa7134.h b/linux/drivers/media/video/saa7134/saa7134.h index 4a9bebb2d..c438682cd 100644 --- a/linux/drivers/media/video/saa7134/saa7134.h +++ b/linux/drivers/media/video/saa7134/saa7134.h @@ -268,6 +268,7 @@ struct saa7134_format { #define SAA7134_BOARD_BEHOLD_M63 143 #define SAA7134_BOARD_BEHOLD_M6_EXTRA 144 #define SAA7134_BOARD_AVERMEDIA_M103 145 +#define SAA7134_BOARD_ASUSTeK_P7131_ANALOG 146 #define SAA7134_MAXBOARDS 8 #define SAA7134_INPUT_MAX 8 -- cgit v1.2.3 From 1256e66660d3ac435768ff432e02a5fa45c572cb Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 12 Jul 2008 10:24:29 -0300 Subject: saa7134: fix compilation From: Mauro Carvalho Chehab Previous patch added a macro that it is not yet defined. Disable that part of the code for now. Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/saa7134/saa7134-cards.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/linux/drivers/media/video/saa7134/saa7134-cards.c b/linux/drivers/media/video/saa7134/saa7134-cards.c index 0d4dca518..08597a558 100644 --- a/linux/drivers/media/video/saa7134/saa7134-cards.c +++ b/linux/drivers/media/video/saa7134/saa7134-cards.c @@ -6078,6 +6078,8 @@ int saa7134_board_init2(struct saa7134_dev *dev) i2c_transfer(&dev->i2c_adap, &msg, 1); break; } +#if 0 + /* FIXME: This entry doesn't exist yet */ case SAA7134_BOARD_ASUSTeK_TVFM35: /* The card below is detected as card=53, but is different */ if (dev->autodetected && (dev->eedata[0x27] == 0x03)) { @@ -6087,6 +6089,7 @@ int saa7134_board_init2(struct saa7134_dev *dev) dev->name, saa7134_boards[dev->board].name); } break; +#endif case SAA7134_BOARD_HAUPPAUGE_HVR1110: hauppauge_eeprom(dev, dev->eedata+0x80); /* break intentionally omitted */ -- cgit v1.2.3 From 190e141537f3ae800c3381d7a5713c04cb71f342 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 12 Jul 2008 16:42:59 -0300 Subject: Update checkpatch.pl with the latest one From: Mauro Carvalho Chehab Signed-off-by: Mauro Carvalho Chehab --- v4l/scripts/checkpatch.pl | 409 +++++++++++++++++++++++++++++++--------------- 1 file changed, 280 insertions(+), 129 deletions(-) diff --git a/v4l/scripts/checkpatch.pl b/v4l/scripts/checkpatch.pl index 511935699..6971bf078 100755 --- a/v4l/scripts/checkpatch.pl +++ b/v4l/scripts/checkpatch.pl @@ -9,7 +9,7 @@ use strict; my $P = $0; $P =~ s@.*/@@g; -my $V = '0.16'; +my $V = '0.19'; use Getopt::Long qw(:config no_auto_abbrev); @@ -115,6 +115,7 @@ our $Attribute = qr{ __kprobes| __(?:mem|cpu|dev|)(?:initdata|init) }x; +our $Modifier; our $Inline = qr{inline|__always_inline|noinline}; our $Member = qr{->$Ident|\.$Ident|\[[^]]*\]}; our $Lval = qr{$Ident(?:$Member)*}; @@ -131,19 +132,30 @@ our $NonptrType; our $Type; our $Declare; +our $UTF8 = qr { + [\x09\x0A\x0D\x20-\x7E] # ASCII + | [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte + | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs + | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte + | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates + | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3 + | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15 + | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16 +}x; + our @typeList = ( qr{void}, - qr{char}, - qr{short}, - qr{int}, - qr{long}, + qr{(?:unsigned\s+)?char}, + qr{(?:unsigned\s+)?short}, + qr{(?:unsigned\s+)?int}, + qr{(?:unsigned\s+)?long}, + qr{(?:unsigned\s+)?long\s+int}, + qr{(?:unsigned\s+)?long\s+long}, + qr{(?:unsigned\s+)?long\s+long\s+int}, qr{unsigned}, qr{float}, qr{double}, qr{bool}, - qr{long\s+int}, - qr{long\s+long}, - qr{long\s+long\s+int}, qr{(?:__)?(?:u|s|be|le)(?:8|16|32|64)}, qr{struct\s+$Ident}, qr{union\s+$Ident}, @@ -152,26 +164,29 @@ our @typeList = ( qr{${Ident}_handler}, qr{${Ident}_handler_fn}, ); +our @modifierList = ( + qr{fastcall}, +); sub build_types { + my $mods = "(?: \n" . join("|\n ", @modifierList) . "\n)"; my $all = "(?: \n" . join("|\n ", @typeList) . "\n)"; $NonptrType = qr{ - \b (?:const\s+)? - (?:unsigned\s+)? + (?:$mods\s+)? (?: - $all| - (?:typeof|__typeof__)\s*\(\s*\**\s*$Ident\s*\) + (?:typeof|__typeof__)\s*\(\s*\**\s*$Ident\s*\)| + (?:${all}\b) ) (?:\s+$Sparse|\s+const)* - \b }x; $Type = qr{ - \b$NonptrType\b + $NonptrType (?:\s*\*+\s*const|\s*\*+|(?:\s*\[\s*\])+)? - (?:\s+$Inline|\s+$Sparse|\s+$Attribute)* + (?:\s+$Inline|\s+$Sparse|\s+$Attribute|\s+$mods)* }x; $Declare = qr{(?:$Storage\s+)?$Type}; + $Modifier = qr{(?:$Attribute|$Sparse|$mods)}; } build_types(); @@ -318,7 +333,7 @@ sub sanitise_line { $off++; next; } - if (substr($line, $off, 2) eq $sanitise_quote) { + if (substr($line, $off, 2) eq '*/') { $sanitise_quote = ''; substr($res, $off, 2, "$;$;"); $off++; @@ -355,14 +370,14 @@ sub sanitise_line { } # The pathname on a #include may be surrounded by '<' and '>'. - if ($res =~ /^.#\s*include\s+\<(.*)\>/) { + if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) { my $clean = 'X' x length($1); $res =~ s@\<.*\>@<$clean>@; # The whole of a #error is a string. - } elsif ($res =~ /^.#\s*(?:error|warning)\s+(.*)\b/) { + } elsif ($res =~ /^.\s*\#\s*(?:error|warning)\s+(.*)\b/) { my $clean = 'X' x length($1); - $res =~ s@(#\s*(?:error|warning)\s+).*@$1$clean@; + $res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@; } return $res; @@ -692,7 +707,7 @@ sub annotate_values { while (length($cur)) { @av_paren_type = ('E') if ($#av_paren_type < 0); print " <" . join('', @av_paren_type) . - "> <$type> " if ($dbg_values > 1); + "> <$type> <$av_pending>" if ($dbg_values > 1); if ($cur =~ /^(\s+)/o) { print "WS($1)\n" if ($dbg_values > 1); if ($1 =~ /\n/ && $av_preprocessor) { @@ -704,28 +719,37 @@ sub annotate_values { print "DECLARE($1)\n" if ($dbg_values > 1); $type = 'T'; - } elsif ($cur =~ /^(#\s*define\s*$Ident)(\(?)/o) { - print "DEFINE($1)\n" if ($dbg_values > 1); + } elsif ($cur =~ /^(\#\s*define\s*$Ident)(\(?)/o) { + print "DEFINE($1,$2)\n" if ($dbg_values > 1); $av_preprocessor = 1; - $av_pending = 'N'; + push(@av_paren_type, $type); + if ($2 ne '') { + $av_pending = 'N'; + } + $type = 'E'; - } elsif ($cur =~ /^(#\s*(?:ifdef|ifndef|if))/o) { + } elsif ($cur =~ /^(\#\s*(?:undef\s*$Ident|include\b))/o) { + print "UNDEF($1)\n" if ($dbg_values > 1); + $av_preprocessor = 1; + push(@av_paren_type, $type); + + } elsif ($cur =~ /^(\#\s*(?:ifdef|ifndef|if))/o) { print "PRE_START($1)\n" if ($dbg_values > 1); $av_preprocessor = 1; push(@av_paren_type, $type); push(@av_paren_type, $type); - $type = 'N'; + $type = 'E'; - } elsif ($cur =~ /^(#\s*(?:else|elif))/o) { + } elsif ($cur =~ /^(\#\s*(?:else|elif))/o) { print "PRE_RESTART($1)\n" if ($dbg_values > 1); $av_preprocessor = 1; push(@av_paren_type, $av_paren_type[$#av_paren_type]); - $type = 'N'; + $type = 'E'; - } elsif ($cur =~ /^(#\s*(?:endif))/o) { + } elsif ($cur =~ /^(\#\s*(?:endif))/o) { print "PRE_END($1)\n" if ($dbg_values > 1); $av_preprocessor = 1; @@ -734,11 +758,16 @@ sub annotate_values { # one does, and continue as if the #endif was not here. pop(@av_paren_type); push(@av_paren_type, $type); - $type = 'N'; + $type = 'E'; } elsif ($cur =~ /^(\\\n)/o) { print "PRECONT($1)\n" if ($dbg_values > 1); + } elsif ($cur =~ /^(__attribute__)\s*\(?/o) { + print "ATTR($1)\n" if ($dbg_values > 1); + $av_pending = $type; + $type = 'N'; + } elsif ($cur =~ /^(sizeof)\s*(\()?/o) { print "SIZEOF($1)\n" if ($dbg_values > 1); if (defined $2) { @@ -812,14 +841,26 @@ sub annotate_values { sub possible { my ($possible, $line) = @_; - #print "CHECK<$possible>\n"; + print "CHECK<$possible> ($line)\n" if ($dbg_possible > 1); if ($possible !~ /^(?:$Storage|$Type|DEFINE_\S+)$/ && $possible ne 'goto' && $possible ne 'return' && - $possible ne 'struct' && $possible ne 'enum' && $possible ne 'case' && $possible ne 'else' && - $possible ne 'typedef') { - warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible); - push(@typeList, $possible); + $possible ne 'asm' && + $possible !~ /^(typedef|struct|enum)\b/) { + # Check for modifiers. + $possible =~ s/\s*$Storage\s*//g; + $possible =~ s/\s*$Sparse\s*//g; + if ($possible =~ /^\s*$/) { + + } elsif ($possible =~ /\s/) { + $possible =~ s/\s*$Type\s*//g; + warn "MODIFIER: $possible ($line)\n" if ($dbg_possible); + push(@modifierList, $possible); + + } else { + warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible); + push(@typeList, $possible); + } build_types(); } } @@ -924,13 +965,14 @@ sub process { } else { $realcnt=1+1; } + $in_comment = 0; # Guestimate if this is a continuing comment. Run # the context looking for a comment "edge". If this # edge is a close comment then we must be in a comment # at context start. my $edge; - for (my $ln = $linenr; $ln < ($linenr + $realcnt); $ln++) { + for (my $ln = $linenr + 1; $ln < ($linenr + $realcnt); $ln++) { next if ($line =~ /^-/); ($edge) = ($rawlines[$ln - 1] =~ m@(/\*|\*/)@); last if (defined $edge); @@ -951,9 +993,9 @@ sub process { ##print "COMMENT:$in_comment edge<$edge> $rawline\n"; sanitise_line_reset($in_comment); - } elsif ($realcnt) { + } elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) { # Standardise the strings and chars within the input to - # simplify matching. + # simplify matching -- only bother with positive lines. $line = sanitise_line($rawline); } push(@lines, $line); @@ -1066,17 +1108,14 @@ sub process { # UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php if (($realfile =~ /^$/ || $line =~ /^\+/) && - !($rawline =~ m/^( - [\x09\x0A\x0D\x20-\x7E] # ASCII - | [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte - | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs - | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte - | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates - | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3 - | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15 - | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16 - )*$/x )) { - ERROR("Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $herecurr); + $rawline !~ m/^$UTF8*$/) { + my ($utf8_prefix) = ($rawline =~ /^($UTF8*)/); + + my $blank = copy_spacing($rawline); + my $ptr = substr($blank, 0, length($utf8_prefix)) . "^"; + my $hereptr = "$hereline$ptr\n"; + + ERROR("Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr); } #ignore lines being removed @@ -1095,7 +1134,9 @@ sub process { ERROR("trailing whitespace\n" . $herevet); } #80 column limit - if ($line =~ /^\+/ && !($prevrawline=~/\/\*\*/) && $length > 80) { + if ($line =~ /^\+/ && $prevrawline !~ /\/\*\*/ && + $rawline !~ /^.\s*\*\s*\@$Ident\s/ && $length > 80) + { WARN("line over 80 characters\n" . $herecurr); } @@ -1112,7 +1153,7 @@ sub process { if ($rawline =~ /^\+\s* \t\s*\S/ || $rawline =~ /^\+\s* \s*/) { my $herevet = "$here\n" . cat_vet($rawline) . "\n"; - ERROR("use tabs not spaces\n" . $herevet); + ERROR("code indent should use tabs where possible\n" . $herevet); } # check for RCS/CVS revision markers @@ -1121,35 +1162,42 @@ sub process { } # Check for potential 'bare' types - if ($realcnt) { - my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0); - $s =~ s/\n./ /g; - $s =~ s/{.*$//; + my ($stat, $cond); + if ($realcnt && $line =~ /.\s*\S/) { + ($stat, $cond) = ctx_statement_block($linenr, + $realcnt, 0); + $stat =~ s/\n./\n /g; + $cond =~ s/\n./\n /g; + + my $s = $stat; + $s =~ s/{.*$//s; # Ignore goto labels. - if ($s =~ /$Ident:\*$/) { + if ($s =~ /$Ident:\*$/s) { # Ignore functions being called - } elsif ($s =~ /^.\s*$Ident\s*\(/) { - - # definitions in global scope can only start with types - } elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b/) { - possible($1, $s); + } elsif ($s =~ /^.\s*$Ident\s*\(/s) { # declarations always start with types - } elsif ($prev_values eq 'E' && $s =~ /^.\s*(?:$Storage\s+)?(?:const\s+)?($Ident)\b(:?\s+$Sparse)?\s*\**\s*$Ident\s*(?:;|=|,)/) { - possible($1, $s); + } elsif ($prev_values eq 'E' && $s =~ /^.\s*(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?((?:\s*$Ident)+)\b(?:\s+$Sparse)?\s*\**\s*(?:$Ident|\(\*[^\)]*\))\s*(?:;|=|,|\()/s) { + my $type = $1; + $type =~ s/\s+/ /g; + possible($type, "A:" . $s); + + # definitions in global scope can only start with types + } elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b/s) { + possible($1, "B:" . $s); } # any (foo ... *) is a pointer cast, and foo is a type - while ($s =~ /\(($Ident)(?:\s+$Sparse)*\s*\*+\s*\)/g) { - possible($1, $s); + while ($s =~ /\(($Ident)(?:\s+$Sparse)*\s*\*+\s*\)/sg) { + possible($1, "C:" . $s); } # Check for any sort of function declaration. # int foo(something bar, other baz); # void (*store_gdt)(x86_descr_ptr *); - if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/) { + if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/s) { my ($name_len) = length($1); my $ctx = $s; @@ -1157,9 +1205,9 @@ sub process { $ctx =~ s/\)[^\)]*$//; for my $arg (split(/\s*,\s*/, $ctx)) { - if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/ || $arg =~ /^($Ident)$/) { + if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/s || $arg =~ /^($Ident)$/s) { - possible($1, $s); + possible($1, "D:" . $s); } } } @@ -1194,7 +1242,7 @@ sub process { # if/while/etc brace do not go on next line, unless defining a do while loop, # or if that brace on the next line is for something else - if ($line =~ /(.*)\b((?:if|while|for|switch)\s*\(|do\b|else\b)/ && $line !~ /^.#/) { + if ($line =~ /(.*)\b((?:if|while|for|switch)\s*\(|do\b|else\b)/ && $line !~ /^.\s*\#/) { my $pre_ctx = "$1$2"; my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0); @@ -1212,7 +1260,7 @@ sub process { if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln -1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) { ERROR("that open brace { should be on the previous line\n" . - "$here\n$ctx\n$lines[$ctx_ln - 1]"); + "$here\n$ctx\n$lines[$ctx_ln - 1]\n"); } if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ && $ctx =~ /\)\s*\;\s*$/ && @@ -1221,7 +1269,7 @@ sub process { my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]); if ($nindent > $indent) { WARN("trailing semicolon indicates no statements, indent implies otherwise\n" . - "$here\n$ctx\n$lines[$ctx_ln - 1]"); + "$here\n$ctx\n$lines[$ctx_ln - 1]\n"); } } } @@ -1257,7 +1305,7 @@ sub process { # # check for malformed paths in #include statements (uses RAW line) - if ($rawline =~ m{^.#\s*include\s+[<"](.*)[">]}) { + if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) { my $path = $1; if ($path =~ m{//}) { ERROR("malformed #include filename\n" . @@ -1282,18 +1330,19 @@ sub process { ($prevline !~ /^ }/) && ($prevline !~ /^.DECLARE_$Ident\(\Q$name\E\)/) && ($prevline !~ /^.LIST_HEAD\(\Q$name\E\)/) && + ($prevline !~ /^.$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(/) && ($prevline !~ /\b\Q$name\E(?:\s+$Attribute)?\s*(?:;|=|\[)/)) { WARN("EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr); } } # check for external initialisers. - if ($line =~ /^.$Type\s*$Ident\s*=\s*(0|NULL);/) { + if ($line =~ /^.$Type\s*$Ident\s*(?:\s+$Modifier)*\s*=\s*(0|NULL|false)\s*;/) { ERROR("do not initialise externals to 0 or NULL\n" . $herecurr); } # check for static initialisers. - if ($line =~ /\s*static\s.*=\s*(0|NULL);/) { + if ($line =~ /\s*static\s.*=\s*(0|NULL|false)\s*;/) { ERROR("do not initialise statics to 0 or NULL\n" . $herecurr); } @@ -1302,6 +1351,7 @@ sub process { # make sense. if ($line =~ /\btypedef\s/ && $line !~ /\btypedef\s+$Type\s+\(\s*\*?$Ident\s*\)\s*\(/ && + $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ && $line !~ /\b__bitwise(?:__|)\b/) { WARN("do not add new typedefs\n" . $herecurr); } @@ -1360,8 +1410,8 @@ sub process { # function brace can't be on same line, except for #defines of do while, # or if closed on same line - if (($line=~/$Type\s*[A-Za-z\d_]+\(.*\).*\s{/) and - !($line=~/\#define.*do\s{/) and !($line=~/}/)) { + if (($line=~/$Type\s*$Ident\(.*\).*\s{/) and + !($line=~/\#\s*define.*do\s{/) and !($line=~/}/)) { ERROR("open brace '{' following function declarations go on the next line\n" . $herecurr); } @@ -1388,10 +1438,10 @@ sub process { # cpp #define statements have non-optional spaces, ie # if there is a space between the name and the open # parenthesis it is simply not a parameter group. - } elsif ($ctx_before =~ /^.\#\s*define\s*$/) { + } elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) { # cpp #elif statement condition may start with a ( - } elsif ($ctx =~ /^.\#\s*elif\s*$/) { + } elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) { # If this whole things ends with a type its most # likely a typedef for a function. @@ -1508,11 +1558,14 @@ sub process { # none after. May be left adjacent to another # unary operator, or a cast } elsif ($op eq '!' || $op eq '~' || - ($is_unary && ($op eq '*' || $op eq '-' || $op eq '&'))) { + ($is_unary && ($op eq '*' || $op eq '-' || $op eq '&'))) { if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) { ERROR("space required before that '$op' $at\n" . $hereptr); } - if ($ctx =~ /.xW/) { + if ($op eq '*' && $cc =~/\s*const\b/) { + # A unary '*' may be const + + } elsif ($ctx =~ /.xW/) { ERROR("space prohibited after that '$op' $at\n" . $hereptr); } @@ -1594,13 +1647,14 @@ sub process { ERROR("space prohibited before that close square bracket ']'\n" . $herecurr); } -# check spacing on paretheses +# check spacing on parentheses if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ && $line !~ /for\s*\(\s+;/) { ERROR("space prohibited after that open parenthesis '('\n" . $herecurr); } if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ && - $line !~ /for\s*\(.*;\s+\)/) { + $line !~ /for\s*\(.*;\s+\)/ && + $line !~ /:\s+\)/) { ERROR("space prohibited before that close parenthesis ')'\n" . $herecurr); } @@ -1610,6 +1664,23 @@ sub process { WARN("labels should not be indented\n" . $herecurr); } +# Return is not a function. + if (defined($stat) && $stat =~ /^.\s*return(\s*)(\(.*);/s) { + my $spacing = $1; + my $value = $2; + + # Flatten any parentheses and braces + while ($value =~ s/\([^\(\)]*\)/1/) { + } + + if ($value =~ /^(?:$Ident|-?$Constant)$/) { + ERROR("return is not a function, parentheses are not required\n" . $herecurr); + + } elsif ($spacing !~ /\s+/) { + ERROR("space required before the open parenthesis '('\n" . $herecurr); + } + } + # Need a space before open parenthesis after if, while etc if ($line=~/\b(if|while|for|switch)\(/) { ERROR("space required before the open parenthesis '('\n" . $herecurr); @@ -1617,7 +1688,7 @@ sub process { # Check for illegal assignment in if conditional. if ($line =~ /\bif\s*\(/) { - my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0); + my ($s, $c) = ($stat, $cond); if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/) { ERROR("do not use assignment in if condition\n" . $herecurr); @@ -1629,7 +1700,7 @@ sub process { $s =~ s/\n.*//g; $s =~ s/$;//g; # Remove any comments if (length($c) && $s !~ /^\s*({|;|)\s*\\*\s*$/ && - $c !~ /^.\#\s*if/) + $c !~ /^.\s*\#\s*if/) { ERROR("trailing statements should be on next line\n" . $herecurr); } @@ -1688,14 +1759,16 @@ sub process { # } #no spaces allowed after \ in define - if ($line=~/\#define.*\\\s$/) { + if ($line=~/\#\s*define.*\\\s$/) { WARN("Whitepspace after \\ makes next lines useless\n" . $herecurr); } #warn if is #included and is available (uses RAW line) - if ($tree && $rawline =~ m{^.\#\s*include\s*\}) { - my $checkfile = "$root/include/linux/$1.h"; - if (-f $checkfile && $1 ne 'irq.h') { + if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\}) { + my $checkfile = "include/linux/$1.h"; + if (-f "$root/$checkfile" && $realfile ne $checkfile && + $1 ne 'irq') + { WARN("Use #include instead of \n" . $herecurr); } @@ -1704,45 +1777,87 @@ sub process { # multi-statement macros should be enclosed in a do while loop, grab the # first statement and ensure its the whole macro if its not enclosed # in a known good container - if ($prevline =~ /\#define.*\\/ && - $prevline !~/(?:do\s+{|\(\{|\{)/ && - $line !~ /(?:do\s+{|\(\{|\{)/ && - $line !~ /^.\s*$Declare\s/) { - # Grab the first statement, if that is the entire macro - # its ok. This may start either on the #define line - # or the one below. + if ($line =~ /^.\s*\#\s*define\s*$Ident(\()?/) { my $ln = $linenr; my $cnt = $realcnt; - my $off = 0; + my ($off, $dstat, $dcond, $rest); + my $ctx = ''; - # If the macro starts on the define line start - # grabbing the statement after the identifier - $prevline =~ m{^(.#\s*define\s*$Ident(?:\([^\)]*\))?\s*)(.*)\\\s*$}; - ##print "1<$1> 2<$2>\n"; - if (defined $2 && $2 ne '') { - $off = length($1); - $ln--; - $cnt++; - while ($lines[$ln - 1] =~ /^-/) { - $ln--; - $cnt++; - } + my $args = defined($1); + + # Find the end of the macro and limit our statement + # search to that. + while ($cnt > 0 && defined $lines[$ln - 1] && + $lines[$ln - 1] =~ /^(?:-|..*\\$)/) + { + $ctx .= $rawlines[$ln - 1] . "\n"; + $ln++; + $cnt--; } - my @ctx = ctx_statement($ln, $cnt, $off); - my $ctx_ln = $ln + $#ctx + 1; - my $ctx = join("\n", @ctx); + $ctx .= $rawlines[$ln - 1]; + + ($dstat, $dcond, $ln, $cnt, $off) = + ctx_statement_block($linenr, $ln - $linenr + 1, 0); + #print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n"; + #print "LINE<$lines[$ln]> len<" . length($lines[$ln]) . "\n"; + + # Extract the remainder of the define (if any) and + # rip off surrounding spaces, and trailing \'s. + $rest = ''; + if (defined $lines[$ln - 1] && + $off > length($lines[$ln - 1])) + { + $ln++; + $cnt--; + $off = 0; + } + while ($cnt > 0) { + $rest .= substr($lines[$ln - 1], $off) . "\n"; + $ln++; + $cnt--; + $off = 0; + } + $rest =~ s/\\\n.//g; + $rest =~ s/^\s*//s; + $rest =~ s/\s*$//s; - # Pull in any empty extension lines. - while ($ctx =~ /\\$/ && - $lines[$ctx_ln - 1] =~ /^.\s*(?:\\)?$/) { - $ctx .= $lines[$ctx_ln - 1]; - $ctx_ln++; + # Clean up the original statement. + if ($args) { + substr($dstat, 0, length($dcond), ''); + } else { + $dstat =~ s/^.\s*\#\s*define\s+$Ident\s*//; } + $dstat =~ s/\\\n.//g; + $dstat =~ s/^\s*//s; + $dstat =~ s/\s*$//s; - if ($ctx =~ /\\$/) { - if ($ctx =~ /;/) { + # Flatten any parentheses and braces + while ($dstat =~ s/\([^\(\)]*\)/1/) { + } + while ($dstat =~ s/\{[^\{\}]*\}/1/) { + } + + my $exceptions = qr{ + $Declare| + module_param_named| + MODULE_PARAM_DESC| + DECLARE_PER_CPU| + DEFINE_PER_CPU| + __typeof__\( + }x; + if ($rest ne '') { + if ($rest !~ /while\s*\(/ && + $dstat !~ /$exceptions/) + { ERROR("Macros with multiple statements should be enclosed in a do - while loop\n" . "$here\n$ctx\n"); - } else { + } + + } elsif ($ctx !~ /;/) { + if ($dstat ne '' && + $dstat !~ /^(?:$Ident|-?$Constant)$/ && + $dstat !~ /$exceptions/ && + $dstat =~ /$Operators/) + { ERROR("Macros with complex values should be enclosed in parenthesis\n" . "$here\n$ctx\n"); } } @@ -1853,7 +1968,7 @@ sub process { # don't include deprecated include files (uses RAW line) for my $inc (@dep_includes) { - if ($rawline =~ m@\#\s*include\s*\<$inc>@) { + if ($rawline =~ m@^.\s*\#\s*include\s*\<$inc>@) { ERROR("Don't use <$inc>: see Documentation/feature-removal-schedule.txt\n" . $herecurr); } } @@ -1877,7 +1992,7 @@ sub process { } # warn about #if 0 - if ($line =~ /^.#\s*if\s+0\b/) { + if ($line =~ /^.\s*\#\s*if\s+0\b/) { CHK("if this code is redundant consider removing it\n" . $herecurr); } @@ -1891,19 +2006,20 @@ sub process { } # warn about #ifdefs in C files -# if ($line =~ /^.#\s*if(|n)def/ && ($realfile =~ /\.c$/)) { +# if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) { # print "#ifdef in C files should be avoided\n"; # print "$herecurr"; # $clean = 0; # } # warn about spacing in #ifdefs - if ($line =~ /^.#\s*(ifdef|ifndef|elif)\s\s+/) { + if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) { ERROR("exactly one space required after that #$1\n" . $herecurr); } # check for spinlock_t definitions without a comment. - if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/) { + if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/ || + $line =~ /^.\s*(DEFINE_MUTEX)\s*\(/) { my $which = $1; if (!ctx_has_comment($first_line, $linenr)) { CHK("$1 definition without comment\n" . $herecurr); @@ -1916,7 +2032,7 @@ sub process { } } # check of hardware specific defines - if ($line =~ m@^.#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) { + if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) { CHK("architecture specific defines should be avoided\n" . $herecurr); } @@ -1933,7 +2049,29 @@ sub process { } # check for new externs in .c files. - if ($line =~ /^.\s*extern\s/ && ($realfile =~ /\.c$/)) { + if ($realfile =~ /\.c$/ && defined $stat && + $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s) + { + my $function_name = $1; + my $paren_space = $2; + + my $s = $stat; + if (defined $cond) { + substr($s, 0, length($cond), ''); + } + if ($s =~ /^\s*;/ && + $function_name ne 'uninitialized_var') + { + WARN("externs should be avoided in .c files\n" . $herecurr); + } + + if ($paren_space =~ /\n/) { + WARN("arguments for function declarations should follow identifier\n" . $herecurr); + } + + } elsif ($realfile =~ /\.c$/ && defined $stat && + $stat =~ /^.\s*extern\s+/) + { WARN("externs should be avoided in .c files\n" . $herecurr); } @@ -1957,11 +2095,11 @@ sub process { } # check for semaphores used as mutexes - if ($line =~ /\b(DECLARE_MUTEX|init_MUTEX)\s*\(/) { + if ($line =~ /^.\s*(DECLARE_MUTEX|init_MUTEX)\s*\(/) { WARN("mutexes are preferred for single holder semaphores\n" . $herecurr); } # check for semaphores used as mutexes - if ($line =~ /\binit_MUTEX_LOCKED\s*\(/) { + if ($line =~ /^.\s*init_MUTEX_LOCKED\s*\(/) { WARN("consider using a completion\n" . $herecurr); } # recommend strict_strto* over simple_strto* @@ -1972,11 +2110,24 @@ sub process { # use of NR_CPUS is usually wrong # ignore definitions of NR_CPUS and usage to define arrays as likely right if ($line =~ /\bNR_CPUS\b/ && - $line !~ /^.#\s*define\s+NR_CPUS\s+/ && - $line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/) + $line !~ /^.\s*\s*#\s*if\b.*\bNR_CPUS\b/ && + $line !~ /^.\s*\s*#\s*define\b.*\bNR_CPUS\b/ && + $line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/ && + $line !~ /\[[^\]]*\.\.\.[^\]]*NR_CPUS[^\]]*\]/ && + $line !~ /\[[^\]]*NR_CPUS[^\]]*\.\.\.[^\]]*\]/) { WARN("usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\n" . $herecurr); } + +# check for %L{u,d,i} in strings + my $string; + while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) { + $string = substr($rawline, $-[1], $+[1] - $-[1]); + if ($string =~ /(?